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  }