github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/apiserver/facades/agent/proxyupdater/proxyupdater_test.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 package proxyupdater_test 5 6 import ( 7 "time" 8 9 "github.com/juju/testing" 10 jc "github.com/juju/testing/checkers" 11 gc "gopkg.in/check.v1" 12 "gopkg.in/juju/names.v2" 13 "gopkg.in/juju/worker.v1/workertest" 14 15 "github.com/juju/juju/apiserver/common" 16 "github.com/juju/juju/apiserver/facades/agent/proxyupdater" 17 "github.com/juju/juju/apiserver/params" 18 apiservertesting "github.com/juju/juju/apiserver/testing" 19 "github.com/juju/juju/environs/config" 20 "github.com/juju/juju/network" 21 "github.com/juju/juju/state" 22 coretesting "github.com/juju/juju/testing" 23 ) 24 25 type ProxyUpdaterSuite struct { 26 coretesting.BaseSuite 27 apiservertesting.StubNetwork 28 29 state *stubBackend 30 resources *common.Resources 31 authorizer apiservertesting.FakeAuthorizer 32 facade *proxyupdater.APIv2 33 tag names.MachineTag 34 } 35 36 var _ = gc.Suite(&ProxyUpdaterSuite{}) 37 38 func (s *ProxyUpdaterSuite) SetUpSuite(c *gc.C) { 39 s.BaseSuite.SetUpSuite(c) 40 s.StubNetwork.SetUpSuite(c) 41 } 42 43 func (s *ProxyUpdaterSuite) SetUpTest(c *gc.C) { 44 s.BaseSuite.SetUpTest(c) 45 s.resources = common.NewResources() 46 s.AddCleanup(func(_ *gc.C) { s.resources.StopAll() }) 47 s.authorizer = apiservertesting.FakeAuthorizer{ 48 Tag: names.NewMachineTag("1"), 49 Controller: false, 50 } 51 s.tag = names.NewMachineTag("1") 52 s.state = &stubBackend{} 53 s.state.SetUp(c) 54 s.AddCleanup(func(_ *gc.C) { s.state.Kill() }) 55 56 api, err := proxyupdater.NewAPIBase(s.state, s.resources, s.authorizer) 57 c.Assert(err, jc.ErrorIsNil) 58 c.Assert(api, gc.NotNil) 59 s.facade = &proxyupdater.APIv2{api} 60 61 // Shouldn't have any calls yet 62 apiservertesting.CheckMethodCalls(c, s.state.Stub) 63 } 64 65 func (s *ProxyUpdaterSuite) TestWatchForProxyConfigAndAPIHostPortChanges(c *gc.C) { 66 // WatchForProxyConfigAndAPIHostPortChanges combines WatchForModelConfigChanges 67 // and WatchAPIHostPorts. Check that they are both called and we get the 68 result := s.facade.WatchForProxyConfigAndAPIHostPortChanges(s.oneEntity()) 69 c.Assert(result.Results, gc.HasLen, 1) 70 c.Assert(result.Results[0].Error, gc.IsNil) 71 72 s.state.Stub.CheckCallNames(c, 73 "WatchForModelConfigChanges", 74 "WatchAPIHostPortsForAgents", 75 ) 76 77 // Verify the watcher resource was registered. 78 c.Assert(s.resources.Count(), gc.Equals, 1) 79 resource := s.resources.Get(result.Results[0].NotifyWatcherId) 80 watcher, ok := resource.(state.NotifyWatcher) 81 c.Assert(ok, jc.IsTrue) 82 83 // Verify the initial event was consumed. 84 select { 85 case <-watcher.Changes(): 86 c.Fatalf("initial event never consumed") 87 case <-time.After(coretesting.ShortWait): 88 } 89 } 90 91 func (s *ProxyUpdaterSuite) oneEntity() params.Entities { 92 entities := params.Entities{ 93 make([]params.Entity, 1), 94 } 95 entities.Entities[0].Tag = s.tag.String() 96 return entities 97 } 98 99 func (s *ProxyUpdaterSuite) TestProxyConfigV1(c *gc.C) { 100 // Check that the ProxyConfig combines data from ModelConfig and APIHostPorts 101 v1 := &proxyupdater.APIv1{s.facade} 102 cfg := v1.ProxyConfig(s.oneEntity()) 103 104 s.state.Stub.CheckCallNames(c, 105 "ModelConfig", 106 "APIHostPortsForAgents", 107 ) 108 109 noProxy := "0.1.2.3,0.1.2.4,0.1.2.5" 110 111 r := params.ProxyConfigResultV1{ 112 ProxySettings: params.ProxyConfig{ 113 HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: noProxy}, 114 APTProxySettings: params.ProxyConfig{ 115 HTTP: "http://apt http proxy", HTTPS: "https://apt https proxy", FTP: "", NoProxy: ""}, 116 } 117 c.Assert(cfg.Results[0], jc.DeepEquals, r) 118 } 119 120 func (s *ProxyUpdaterSuite) TestProxyConfig(c *gc.C) { 121 // Check that the ProxyConfig combines data from ModelConfig and APIHostPorts 122 cfg := s.facade.ProxyConfig(s.oneEntity()) 123 124 s.state.Stub.CheckCallNames(c, 125 "ModelConfig", 126 "APIHostPortsForAgents", 127 ) 128 129 expectedLegacyNoProxy := "0.1.2.3,0.1.2.4,0.1.2.5" 130 expectedJujuNoProxy := "" 131 132 r := params.ProxyConfigResult{ 133 LegacyProxySettings: params.ProxyConfig{ 134 HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: expectedLegacyNoProxy}, 135 JujuProxySettings: params.ProxyConfig{ 136 HTTP: "", HTTPS: "", FTP: "", NoProxy: expectedJujuNoProxy}, 137 APTProxySettings: params.ProxyConfig{ 138 HTTP: "http://apt http proxy", HTTPS: "https://apt https proxy", FTP: "", NoProxy: ""}, 139 } 140 c.Assert(cfg.Results[0], jc.DeepEquals, r) 141 } 142 143 func (s *ProxyUpdaterSuite) TestProxyConfigJujuProxy(c *gc.C) { 144 s.state.SetModelConfig(coretesting.Attrs{ 145 "juju-http-proxy": "http proxy", 146 "juju-https-proxy": "https proxy", 147 "apt-http-proxy": "apt http proxy", 148 "apt-https-proxy": "apt https proxy", 149 }) 150 151 cfg := s.facade.ProxyConfig(s.oneEntity()) 152 153 s.state.Stub.CheckCallNames(c, 154 "ModelConfig", 155 "APIHostPortsForAgents", 156 ) 157 158 // need to make sure that auto-population/auto-appending of controller IPs to 159 // no-proxy is aware of which proxy settings are used: if non-legacy ones are used 160 // then juju-no-proxy should be auto-modified 161 expectedJujuNoProxy := "0.1.2.3,0.1.2.4,0.1.2.5" 162 expectedLegacyNoProxy := "" 163 164 r := params.ProxyConfigResult{ 165 JujuProxySettings: params.ProxyConfig{ 166 HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: expectedJujuNoProxy}, 167 LegacyProxySettings: params.ProxyConfig{ 168 HTTP: "", HTTPS: "", FTP: "", NoProxy: expectedLegacyNoProxy}, 169 APTProxySettings: params.ProxyConfig{ 170 HTTP: "http://apt http proxy", HTTPS: "https://apt https proxy", FTP: "", NoProxy: ""}, 171 } 172 c.Assert(cfg.Results[0], jc.DeepEquals, r) 173 } 174 175 func (s *ProxyUpdaterSuite) TestProxyConfigExtendsExisting(c *gc.C) { 176 // Check that the ProxyConfig combines data from ModelConfig and APIHostPorts 177 s.state.SetModelConfig(coretesting.Attrs{ 178 "http-proxy": "http proxy", 179 "https-proxy": "https proxy", 180 "apt-http-proxy": "apt http proxy", 181 "apt-https-proxy": "apt https proxy", 182 "no-proxy": "9.9.9.9", 183 }) 184 cfg := s.facade.ProxyConfig(s.oneEntity()) 185 s.state.Stub.CheckCallNames(c, 186 "ModelConfig", 187 "APIHostPortsForAgents", 188 ) 189 190 expectedNoProxy := "0.1.2.3,0.1.2.4,0.1.2.5,9.9.9.9" 191 expectedAptNoProxy := "9.9.9.9" 192 193 c.Assert(cfg.Results[0], jc.DeepEquals, params.ProxyConfigResult{ 194 LegacyProxySettings: params.ProxyConfig{ 195 HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: expectedNoProxy}, 196 APTProxySettings: params.ProxyConfig{ 197 HTTP: "http://apt http proxy", HTTPS: "https://apt https proxy", FTP: "", NoProxy: expectedAptNoProxy}, 198 }) 199 } 200 201 func (s *ProxyUpdaterSuite) TestProxyConfigNoDuplicates(c *gc.C) { 202 // Check that the ProxyConfig combines data from ModelConfig and APIHostPorts 203 s.state.SetModelConfig(coretesting.Attrs{ 204 "http-proxy": "http proxy", 205 "https-proxy": "https proxy", 206 "apt-http-proxy": "apt http proxy", 207 "apt-https-proxy": "apt https proxy", 208 "no-proxy": "0.1.2.3", 209 }) 210 cfg := s.facade.ProxyConfig(s.oneEntity()) 211 s.state.Stub.CheckCallNames(c, 212 "ModelConfig", 213 "APIHostPortsForAgents", 214 ) 215 216 expectedNoProxy := "0.1.2.3,0.1.2.4,0.1.2.5" 217 expectedAptNoProxy := "0.1.2.3" 218 219 c.Assert(cfg.Results[0], jc.DeepEquals, params.ProxyConfigResult{ 220 LegacyProxySettings: params.ProxyConfig{ 221 HTTP: "http proxy", HTTPS: "https proxy", FTP: "", NoProxy: expectedNoProxy}, 222 APTProxySettings: params.ProxyConfig{ 223 HTTP: "http://apt http proxy", HTTPS: "https://apt https proxy", FTP: "", NoProxy: expectedAptNoProxy}, 224 }) 225 } 226 227 func (s *ProxyUpdaterSuite) TestSnapProxyConfig(c *gc.C) { 228 s.state.SetModelConfig(coretesting.Attrs{ 229 "snap-http-proxy": "http proxy", 230 "snap-https-proxy": "https proxy", 231 "snap-store-proxy": "store proxy", 232 "snap-store-assertions": "trust us", 233 }) 234 cfg := s.facade.ProxyConfig(s.oneEntity()) 235 s.state.Stub.CheckCallNames(c, 236 "ModelConfig", 237 "APIHostPortsForAgents", 238 ) 239 240 expectedNoProxy := "0.1.2.3,0.1.2.4,0.1.2.5" 241 242 c.Assert(cfg.Results[0], jc.DeepEquals, params.ProxyConfigResult{ 243 LegacyProxySettings: params.ProxyConfig{NoProxy: expectedNoProxy}, 244 SnapProxySettings: params.ProxyConfig{ 245 HTTP: "http proxy", HTTPS: "https proxy"}, 246 SnapStoreProxyId: "store proxy", 247 SnapStoreProxyAssertions: "trust us", 248 }) 249 } 250 251 type stubBackend struct { 252 *testing.Stub 253 254 EnvConfig *config.Config 255 c *gc.C 256 configAttrs coretesting.Attrs 257 hpWatcher workertest.NotAWatcher 258 confWatcher workertest.NotAWatcher 259 } 260 261 func (sb *stubBackend) SetUp(c *gc.C) { 262 sb.Stub = &testing.Stub{} 263 sb.c = c 264 sb.configAttrs = coretesting.Attrs{ 265 "http-proxy": "http proxy", 266 "https-proxy": "https proxy", 267 "apt-http-proxy": "apt http proxy", 268 "apt-https-proxy": "apt https proxy", 269 } 270 sb.hpWatcher = workertest.NewFakeWatcher(1, 1) 271 sb.confWatcher = workertest.NewFakeWatcher(1, 1) 272 } 273 274 func (sb *stubBackend) Kill() { 275 sb.hpWatcher.Kill() 276 sb.confWatcher.Kill() 277 } 278 279 func (sb *stubBackend) SetModelConfig(ca coretesting.Attrs) { 280 sb.configAttrs = ca 281 } 282 283 func (sb *stubBackend) ModelConfig() (*config.Config, error) { 284 sb.MethodCall(sb, "ModelConfig") 285 if err := sb.NextErr(); err != nil { 286 return nil, err 287 } 288 return coretesting.CustomModelConfig(sb.c, sb.configAttrs), nil 289 } 290 291 func (sb *stubBackend) APIHostPortsForAgents() ([][]network.HostPort, error) { 292 sb.MethodCall(sb, "APIHostPortsForAgents") 293 if err := sb.NextErr(); err != nil { 294 return nil, err 295 } 296 hps := [][]network.HostPort{ 297 network.NewHostPorts(1234, "0.1.2.3"), 298 network.NewHostPorts(1234, "0.1.2.4"), 299 network.NewHostPorts(1234, "0.1.2.5"), 300 } 301 return hps, nil 302 } 303 304 func (sb *stubBackend) WatchAPIHostPortsForAgents() state.NotifyWatcher { 305 sb.MethodCall(sb, "WatchAPIHostPortsForAgents") 306 return sb.hpWatcher 307 } 308 309 func (sb *stubBackend) WatchForModelConfigChanges() state.NotifyWatcher { 310 sb.MethodCall(sb, "WatchForModelConfigChanges") 311 return sb.confWatcher 312 }