1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135
|
// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package proxy
import (
"fmt"
"os"
"strings"
"github.com/juju/utils/set"
)
const (
// Remove the likelihood of errors by mistyping string values.
http_proxy = "http_proxy"
https_proxy = "https_proxy"
ftp_proxy = "ftp_proxy"
no_proxy = "no_proxy"
)
// Settings holds the values for the HTTP, HTTPS and FTP proxies as well as the
// no_proxy value found by Detect Proxies.
// AutoNoProxy is filled with addresses of controllers, we never want to proxy those
type Settings struct {
Http string
Https string
Ftp string
NoProxy string
AutoNoProxy string
}
func getSetting(key string) string {
value := os.Getenv(key)
if value == "" {
value = os.Getenv(strings.ToUpper(key))
}
return value
}
// DetectProxies returns the proxy settings found the environment.
func DetectProxies() Settings {
return Settings{
Http: getSetting(http_proxy),
Https: getSetting(https_proxy),
Ftp: getSetting(ftp_proxy),
NoProxy: getSetting(no_proxy),
}
}
// AsScriptEnvironment returns a potentially multi-line string in a format
// that specifies exported key=value lines. There are two lines for each non-
// empty proxy value, one lower-case and one upper-case.
func (s *Settings) AsScriptEnvironment() string {
var lines []string
addLine := func(proxy, value string) {
if value != "" {
lines = append(
lines,
fmt.Sprintf("export %s=%s", proxy, value),
fmt.Sprintf("export %s=%s", strings.ToUpper(proxy), value))
}
}
addLine(http_proxy, s.Http)
addLine(https_proxy, s.Https)
addLine(ftp_proxy, s.Ftp)
addLine(no_proxy, s.FullNoProxy())
return strings.Join(lines, "\n")
}
// AsEnvironmentValues returns a slice of strings of the format "key=value"
// suitable to be used in a command environment. There are two values for each
// non-empty proxy value, one lower-case and one upper-case.
func (s *Settings) AsEnvironmentValues() []string {
lines := []string{}
addLine := func(proxy, value string) {
if value != "" {
lines = append(
lines,
fmt.Sprintf("%s=%s", proxy, value),
fmt.Sprintf("%s=%s", strings.ToUpper(proxy), value))
}
}
addLine(http_proxy, s.Http)
addLine(https_proxy, s.Https)
addLine(ftp_proxy, s.Ftp)
addLine(no_proxy, s.FullNoProxy())
return lines
}
// AsSystemdEnvSettings returns a string in the format understood by systemd:
// DefaultEnvironment="http_proxy=...." "HTTP_PROXY=..." ...
func (s *Settings) AsSystemdDefaultEnv() string {
lines := s.AsEnvironmentValues()
rv := `# To allow juju to control the global systemd proxy settings,
# create symbolic links to this file from within /etc/systemd/system.conf.d/
# and /etc/systemd/users.conf.d/.
[Manager]
DefaultEnvironment=`
for _, line := range lines {
rv += fmt.Sprintf(`"%s" `, line)
}
return rv + "\n"
}
// SetEnvironmentValues updates the process environment with the
// proxy values stored in the settings object. Both the lower-case
// and upper-case variants are set.
//
// http_proxy, HTTP_PROXY
// https_proxy, HTTPS_PROXY
// ftp_proxy, FTP_PROXY
func (s *Settings) SetEnvironmentValues() {
setenv := func(proxy, value string) {
os.Setenv(proxy, value)
os.Setenv(strings.ToUpper(proxy), value)
}
setenv(http_proxy, s.Http)
setenv(https_proxy, s.Https)
setenv(ftp_proxy, s.Ftp)
setenv(no_proxy, s.FullNoProxy())
}
// FullNoProxy merges NoProxy and AutoNoProxyList
func (s *Settings) FullNoProxy() string {
var allNoProxy []string
if s.NoProxy != "" {
allNoProxy = strings.Split(s.NoProxy, ",")
}
if s.AutoNoProxy != "" {
allNoProxy = append(allNoProxy, strings.Split(s.AutoNoProxy, ",")...)
}
noProxySet := set.NewStrings(allNoProxy...)
return strings.Join(noProxySet.SortedValues(), ",")
}
|