Description:
APIWorker should only connect to API on localhost
In some cases, APIWorker might try to connect
to a different address than localhost in machines
with the ManageEnviron job, in those cases we
change the api hostname from whatever is set
to localhost and keep the port.
+func pickBestHosts(apiInfo *api.Info, jobs []params.MachineJob) error {
+ for _, job := range jobs {
+ if job == params.JobManageEnviron {
+ firstAddr := apiInfo.Addrs[0]
+ _, port, err := net.SplitHostPort(firstAddr)
+ if err != nil {
+ return err
+ }
+ portNum, err := strconv.Atoi(port)
+ if err != nil {
+ return fmt.Errorf("bad port number %q", port)
+ }
+ apiInfo.Addrs = []string{fmt.Sprintf("localhost:%d", portNum)}
+ break
+ }
+ }
+ return nil
+}
+
// openAPIState opens the API using the given information, and
// returns the opened state and the api entity with
// the given tag. The given changeConfig function is
@@ -205,6 +226,12 @@
// then the worker that's calling this cannot
// be interrupted.
info := agentConfig.APIInfo()
+ // Ensure that we conect trough localhost
+ agentConfigJobs := agentConfig.Jobs()
+ if err := pickBestHosts(info, agentConfigJobs); err != nil {
+ return nil, nil, err
+ }
+
st, err := apiOpen(info, api.DialOpts{})
usedOldPassword := false
if params.IsCodeUnauthorized(err) {
Reviewers: mp+221221_ code.launchpad. net,
Message:
Please take a look.
Description:
APIWorker should only connect to API on localhost
In some cases, APIWorker might try to connect
to a different address than localhost in machines
with the ManageEnviron job, in those cases we
change the api hostname from whatever is set
to localhost and keep the port.
https:/ /code.launchpad .net/~hduran- 8/juju- core/apiworker_ force_local_ connection/ +merge/ 221221
(do not edit description out of merge proposal)
Please review this at https:/ /codereview. appspot. com/100810045/
Affected files (+83, -5 lines): agent_test. go
A [revision details]
M cmd/jujud/agent.go
M cmd/jujud/
Index: [revision details] 20140519143554- fd3fvpqfvhm5u64 2
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-
+New revision: <email address hidden>
Index: cmd/jujud/agent.go agent.go'
=== modified file 'cmd/jujud/
--- cmd/jujud/agent.go 2014-05-14 21:13:17 +0000
+++ cmd/jujud/agent.go 2014-05-28 19:00:09 +0000
@@ -6,7 +6,9 @@
import (
"fmt"
"io"
+ "net"
"path/filepath"
+ "strconv"
"sync"
"time"
@@ -191,6 +193,25 @@
type configChanger func(c *agent.Config)
+func pickBestHosts( apiInfo *api.Info, jobs []params. MachineJob) error { JobManageEnviro n { rt(firstAddr) fmt.Sprintf( "localhost: %d", portNum)} APIInfo( ) IsCodeUnauthori zed(err) {
+ for _, job := range jobs {
+ if job == params.
+ firstAddr := apiInfo.Addrs[0]
+ _, port, err := net.SplitHostPo
+ if err != nil {
+ return err
+ }
+ portNum, err := strconv.Atoi(port)
+ if err != nil {
+ return fmt.Errorf("bad port number %q", port)
+ }
+ apiInfo.Addrs = []string{
+ break
+ }
+ }
+ return nil
+}
+
// openAPIState opens the API using the given information, and
// returns the opened state and the api entity with
// the given tag. The given changeConfig function is
@@ -205,6 +226,12 @@
// then the worker that's calling this cannot
// be interrupted.
info := agentConfig.
+ // Ensure that we conect trough localhost
+ agentConfigJobs := agentConfig.Jobs()
+ if err := pickBestHosts(info, agentConfigJobs); err != nil {
+ return nil, nil, err
+ }
+
st, err := apiOpen(info, api.DialOpts{})
usedOldPassword := false
if params.
Index: cmd/jujud/ agent_test. go agent_test. go' agent_test. go 2014-04-30 23:18:40 +0000 agent_test. go 2014-05-28 19:02:43 +0000
=== modified file 'cmd/jujud/
--- cmd/jujud/
+++ cmd/jujud/
@@ -105,17 +105,23 @@
return "old"
}
+func (fakeAPIOpenConfig) Jobs() []params.MachineJob { MachineJob{ } &apiOpenSuite{ })
+ return []params.
+}
+
var _ = gc.Suite(
+type replaceErrors struct { eReplaceErrors( c *gc.C) { (&apiOpen, func(info *api.Info, opts api.DialOpts) Errorf( "blah") , nil, CodeNotProvisio ned}, CodeUnauthorize d}, ErrTerminateAge nt, fakeAPIOpenConf ig{}, nil)
+ openErr error
+ replaceErr error
+}
+
func (s *apiOpenSuite) TestOpenAPIStat
var apiError error
s.PatchValue
(*api.State, error) {
return nil, apiError
})
- for i, test := range []struct {
- openErr error
- replaceErr error
- }{{
+ errReplacePairs := []replaceErrors{{
fmt.
}, {
openErr: ¶ms.Error{Code: params.
@@ -123,7 +129,8 @@
}, {
openErr: ¶ms.Error{Code: params.
replaceErr: worker.
- }} {
+ }}
+ for i, test := range errReplacePairs {
c.Logf("test %d", i)
apiError = test.openErr
_, _, err := openAPIState(
@@ -352,6 +359,48 @@
c.Assert(err, gc.IsNil)
}
+type providedExpecte dAddresses struct { ssChosenForMana geEnviron( c *gc.C) { tedAddresses{ { ess:12345" , MachineJob{ params. JobManageEnviro n}, Address: 12345", Address: 12345", MachineJob{ }, eachDataSet. provided} &apiInfo, eachDataSet.jobs) apiInfo. Addrs[0] , gc.Equals, eachDataSet. expected) kerFailsWithInc ompleteAddress( c *gc.C) &apiInfo, MachineJob{ params. JobManageEnviro n}) apiInfo. Addrs[0] , gc.Equals, "this is an invalid hostname") kerFailsWithMal formedPort( c *gc.C) { "localhost: invalidport" } &apiInfo, MachineJob{ params. JobManageEnviro n}) apiInfo. Addrs[0] , gc.Equals, "localhost: invalidport" ) g(agent. ConfigPath( s.DataDir( ), ent.Tag()))
+ provided string
+ expected string
+ jobs []params.MachineJob
+}
+
+func (s *agentSuite) TestProperAddre
+ apiInfo := api.Info{}
+ addresses := []providedExpec
+ "changeThisAddr
+ "localhost:12345",
+ []params.
+ }, {
+ "dontChangeThis
+ "dontChangeThis
+ []params.
+ },
+ }
+ for _, eachDataSet := range addresses {
+ apiInfo.Addrs = []string{
+ err := pickBestHosts(
+ c.Assert(err, gc.IsNil)
+ c.Assert(
+ }
+}
+
+func (s *agentSuite) TestBestHostPic
{
+ apiInfo := api.Info{}
+ apiInfo.Addrs = []string{"this is an invalid hostname"}
+ err := pickBestHosts(
[]params.
+ c.Check(
+ c.Assert(err, gc.ErrorMatches, "missing port in address this is an
invalid hostname")
+}
+
+func (s *agentSuite) TestBestHostPic
+ apiInfo := api.Info{}
+ apiInfo.Addrs = []string{
+ err := pickBestHosts(
[]params.
+ c.Check(
+ c.Assert(err, gc.ErrorMatches, "bad port number \"invalidport\"")
+}
+
func (s *agentSuite) testOpenAPIState(c *gc.C, ent state.AgentEntity,
agentCmd Agent, initialPassword string) {
conf, err := agent.ReadConfi
c.Assert(err, gc.IsNil)