-
Notifications
You must be signed in to change notification settings - Fork 4
/
proxy.go
148 lines (135 loc) · 3.99 KB
/
proxy.go
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
136
137
138
139
140
141
142
143
144
145
146
147
148
// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package proxy
import (
"fmt"
"os"
"strings"
"github.com/juju/collections/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),
}
}
// HasProxySet returns true if there is a proxy value for HTTP, HTTPS or FTP.
func (s *Settings) HasProxySet() bool {
return s.Http != "" ||
s.Https != "" ||
s.Ftp != ""
}
// 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 {
if !s.HasProxySet() {
return ""
}
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 fmt.Sprintf("%s\n", 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 {
if !s.HasProxySet() {
return nil
}
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(), ",")
}