Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/juju/juju into 135-names-…
Browse files Browse the repository at this point in the history
…refactor-part-viii

Conflicts:
	agent/agent_test.go
  • Loading branch information
davecheney committed Jul 16, 2014
2 parents 029f5c4 + 9c2afa1 commit 88c43de
Show file tree
Hide file tree
Showing 38 changed files with 505 additions and 121 deletions.
23 changes: 20 additions & 3 deletions agent/agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,10 @@ type Config interface {
// Value returns the value associated with the key, or an empty string if
// the key is not found.
Value(key string) string

// PreferIPv6 returns whether to prefer using IPv6 addresses (if
// available) when connecting to the state or API server.
PreferIPv6() bool
}

type ConfigSetterOnly interface {
Expand Down Expand Up @@ -238,6 +242,7 @@ type configInternal struct {
oldPassword string
servingInfo *params.StateServingInfo
values map[string]string
preferIPv6 bool
}

type AgentConfigParams struct {
Expand All @@ -252,6 +257,7 @@ type AgentConfigParams struct {
APIAddresses []string
CACert string
Values map[string]string
PreferIPv6 bool
}

// NewAgentConfig returns a new config object suitable for use for a
Expand Down Expand Up @@ -294,6 +300,7 @@ func NewAgentConfig(configParams AgentConfigParams) (ConfigSetterWriter, error)
caCert: configParams.CACert,
oldPassword: configParams.Password,
values: configParams.Values,
preferIPv6: configParams.PreferIPv6,
}
if len(configParams.StateAddresses) > 0 {
config.stateDetails = &connectionDetails{
Expand Down Expand Up @@ -539,6 +546,10 @@ func (c *configInternal) Value(key string) string {
return c.values[key]
}

func (c *configInternal) PreferIPv6() bool {
return c.preferIPv6
}

func (c *configInternal) StateServingInfo() (params.StateServingInfo, bool) {
if c.servingInfo == nil {
return params.StateServingInfo{}, false
Expand Down Expand Up @@ -626,16 +637,19 @@ func (c *configInternal) APIInfo() *api.Info {
addrs := c.apiDetails.addresses
if isStateServer {
port := servingInfo.APIPort
localApiAddr := fmt.Sprintf("localhost:%d", port)
localAPIAddr := net.JoinHostPort("localhost", strconv.Itoa(port))
if c.preferIPv6 {
localAPIAddr = net.JoinHostPort("::1", strconv.Itoa(port))
}
addrInAddrs := false
for _, addr := range addrs {
if addr == localApiAddr {
if addr == localAPIAddr {
addrInAddrs = true
break
}
}
if !addrInAddrs {
addrs = append(addrs, localApiAddr)
addrs = append(addrs, localAPIAddr)
}
}
return &api.Info{
Expand All @@ -653,6 +667,9 @@ func (c *configInternal) MongoInfo() (info *authentication.MongoInfo, ok bool) {
return nil, false
}
addr := net.JoinHostPort("127.0.0.1", strconv.Itoa(ssi.StatePort))
if c.preferIPv6 {
addr = net.JoinHostPort("::1", strconv.Itoa(ssi.StatePort))
}
return &authentication.MongoInfo{
Info: mongo.Info{
Addrs: []string{addr},
Expand Down
97 changes: 94 additions & 3 deletions agent/agent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,10 +174,40 @@ var agentConfigTests = []struct {
CACert: "ca cert",
StateAddresses: []string{"localhost:1234"},
APIAddresses: []string{"localhost:1235"},
},
inspectConfig: func(c *gc.C, cfg agent.Config) {
c.Check(cfg.Dir(), gc.Equals, "/data/dir/agents/unit-ubuntu-1")
},
}, {
about: "prefer-ipv6 parsed when set",
params: agent.AgentConfigParams{
DataDir: "/data/dir",
Tag: names.NewMachineTag("1"),
Password: "sekrit",
UpgradedToVersion: version.Current.Number,
CACert: "ca cert",
StateAddresses: []string{"localhost:1234"},
APIAddresses: []string{"localhost:1235"},
Nonce: "a nonce",
PreferIPv6: true,
},
inspectConfig: func(c *gc.C, cfg agent.Config) {
c.Check(cfg.PreferIPv6(), jc.IsTrue)
},
}, {
about: "missing prefer-ipv6 defaults to false",
params: agent.AgentConfigParams{
DataDir: "/data/dir",
Tag: names.NewMachineTag("1"),
Password: "sekrit",
UpgradedToVersion: version.Current.Number,
CACert: "ca cert",
StateAddresses: []string{"localhost:1234"},
APIAddresses: []string{"localhost:1235"},
Nonce: "a nonce",
},
inspectConfig: func(c *gc.C, cfg agent.Config) {
c.Assert(cfg.Dir(), gc.Equals, "/data/dir/agents/unit-ubuntu-1")
c.Check(cfg.PreferIPv6(), jc.IsFalse)
},
}}

Expand Down Expand Up @@ -465,7 +495,7 @@ func (*suite) TestWriteAndRead(c *gc.C) {
c.Assert(reread, jc.DeepEquals, conf)
}

func (*suite) TestAPIInfoAddsLocalhostWhenServingInfoPesent(c *gc.C) {
func (*suite) TestAPIInfoAddsLocalhostWhenServingInfoPresent(c *gc.C) {
attrParams := attributeParams
servingInfo := params.StateServingInfo{
Cert: "old cert",
Expand All @@ -489,8 +519,69 @@ func (*suite) TestAPIInfoAddsLocalhostWhenServingInfoPesent(c *gc.C) {
c.Assert(localhostAddressFound, jc.IsTrue)
}

func (*suite) TestAPIInfoDoesntAddLocalhostWhenNoServingInfo(c *gc.C) {
func (*suite) TestAPIInfoAddsLocalhostWhenServingInfoPresentAndPreferIPv6On(c *gc.C) {
attrParams := attributeParams
attrParams.PreferIPv6 = true
servingInfo := params.StateServingInfo{
Cert: "old cert",
PrivateKey: "old key",
StatePort: 69,
APIPort: 1492,
SharedSecret: "shared",
SystemIdentity: "identity",
}
conf, err := agent.NewStateMachineConfig(attrParams, servingInfo)
c.Assert(err, gc.IsNil)
apiinfo := conf.APIInfo()
c.Check(apiinfo.Addrs, gc.HasLen, len(attrParams.APIAddresses)+1)
localhostAddressFound := false
for _, eachApiAddress := range apiinfo.Addrs {
if eachApiAddress == "[::1]:1492" {
localhostAddressFound = true
break
}
c.Check(eachApiAddress, gc.Not(gc.Equals), "localhost:1492")
}
c.Assert(localhostAddressFound, jc.IsTrue)
}

func (*suite) TestMongoInfoHonorsPreferIPv6(c *gc.C) {
attrParams := attributeParams
attrParams.PreferIPv6 = true
servingInfo := params.StateServingInfo{
Cert: "old cert",
PrivateKey: "old key",
StatePort: 69,
APIPort: 1492,
SharedSecret: "shared",
SystemIdentity: "identity",
}
conf, err := agent.NewStateMachineConfig(attrParams, servingInfo)
c.Assert(err, gc.IsNil)
mongoInfo, ok := conf.MongoInfo()
c.Assert(ok, jc.IsTrue)
c.Check(mongoInfo.Info.Addrs, jc.DeepEquals, []string{"[::1]:69"})

attrParams.PreferIPv6 = false
conf, err = agent.NewStateMachineConfig(attrParams, servingInfo)
c.Assert(err, gc.IsNil)
mongoInfo, ok = conf.MongoInfo()
c.Assert(ok, jc.IsTrue)
c.Check(mongoInfo.Info.Addrs, jc.DeepEquals, []string{"127.0.0.1:69"})
}

func (*suite) TestAPIInfoDoesntAddLocalhostWhenNoServingInfoPreferIPv6Off(c *gc.C) {
attrParams := attributeParams
attrParams.PreferIPv6 = false
conf, err := agent.NewAgentConfig(attrParams)
c.Assert(err, gc.IsNil)
apiinfo := conf.APIInfo()
c.Assert(apiinfo.Addrs, gc.DeepEquals, attrParams.APIAddresses)
}

func (*suite) TestAPIInfoDoesntAddLocalhostWhenNoServingInfoPreferIPv6On(c *gc.C) {
attrParams := attributeParams
attrParams.PreferIPv6 = true
conf, err := agent.NewAgentConfig(attrParams)
c.Assert(err, gc.IsNil)
apiinfo := conf.APIInfo()
Expand Down
4 changes: 4 additions & 0 deletions agent/format-1.18.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ type format_1_18Serialization struct {
OldPassword string
Values map[string]string

PreferIPv6 bool `yaml:"prefer-ipv6,omitempty"`

// Only state server machines have these next three items
StateServerCert string `yaml:",omitempty"`
StateServerKey string `yaml:",omitempty"`
Expand Down Expand Up @@ -86,6 +88,7 @@ func (formatter_1_18) unmarshal(data []byte) (*configInternal, error) {
caCert: format.CACert,
oldPassword: format.OldPassword,
values: format.Values,
preferIPv6: format.PreferIPv6,
}
if config.logDir == "" {
config.logDir = DefaultLogDir
Expand Down Expand Up @@ -148,6 +151,7 @@ func (formatter_1_18) marshal(config *configInternal) ([]byte, error) {
CACert: string(config.caCert),
OldPassword: config.oldPassword,
Values: config.values,
PreferIPv6: config.preferIPv6,
}
if config.servingInfo != nil {
format.StateServerCert = config.servingInfo.Cert
Expand Down
4 changes: 4 additions & 0 deletions agent/format-1.18_whitebox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func (s *format_1_18Suite) TestMissingAttributes(c *gc.C) {
c.Assert(readConfig.UpgradedToVersion(), gc.Equals, version.MustParse("1.16.0"))
c.Assert(readConfig.LogDir(), gc.Equals, "/var/log/juju")
c.Assert(readConfig.DataDir(), gc.Equals, "/var/lib/juju")
c.Assert(readConfig.PreferIPv6(), jc.IsFalse)
}

func (s *format_1_18Suite) TestStatePortNotParsedWithoutSecret(c *gc.C) {
Expand All @@ -60,6 +61,7 @@ func (*format_1_18Suite) TestReadConfWithExisting1_18ConfigFileContents(c *gc.C)
c.Assert(err, gc.IsNil)
c.Assert(config.UpgradedToVersion(), jc.DeepEquals, version.MustParse("1.17.5.1"))
c.Assert(config.Jobs(), jc.DeepEquals, []params.MachineJob{params.JobManageEnviron})
c.Assert(config.PreferIPv6(), jc.IsTrue)
}

var agentConfig1_18Contents = `
Expand Down Expand Up @@ -177,6 +179,7 @@ stateserverkey: '-----BEGIN RSA PRIVATE KEY-----
'
apiport: 17070
prefer-ipv6: true
`[1:]

var agentConfig1_18NotStateMachine = `
Expand Down Expand Up @@ -235,4 +238,5 @@ values:
STORAGE_ADDR: 10.0.3.1:8040
STORAGE_DIR: /home/user/.juju/local/storage
apiport: 17070
prefer-ipv6: true
`[1:]
1 change: 1 addition & 0 deletions agent/format_whitebox_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ var agentParams = AgentConfigParams{
StateAddresses: []string{"localhost:1234"},
APIAddresses: []string{"localhost:1235"},
Nonce: "a nonce",
PreferIPv6: false,
}

func newTestConfig(c *gc.C) *configInternal {
Expand Down
54 changes: 19 additions & 35 deletions cmd/juju/addmachine.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@
package main

import (
"errors"
"fmt"
"strings"

"github.com/juju/cmd"
"github.com/juju/errors"
"github.com/juju/names"
"launchpad.net/gnuflag"

Expand Down Expand Up @@ -106,35 +106,37 @@ func (c *AddMachineCommand) Init(args []string) error {
return nil
}

type AddMachineAPI interface {
Close() error
type addMachineAPI interface {
AddMachines([]params.AddMachineParams) ([]params.AddMachinesResult, error)
AddMachines1dot18([]params.AddMachineParams) ([]params.AddMachinesResult, error)
Close() error
DestroyMachines(machines ...string) error
EnvironmentUUID() string
ProvisioningScript(params.ProvisioningScriptParams) (script string, err error)
}

var getAddMachineAPI = func(c *AddMachineCommand) (AddMachineAPI, error) {
var getAddMachineAPI = func(c *AddMachineCommand) (addMachineAPI, error) {
return c.NewAPIClient()
}

func (c *AddMachineCommand) Run(ctx *cmd.Context) error {
client, err := getAddMachineAPI(c)
if err != nil {
return errors.Trace(err)
}
defer client.Close()

if c.Placement != nil && c.Placement.Scope == "ssh" {
args := manual.ProvisionMachineArgs{
Host: c.Placement.Directive,
EnvName: c.ConnectionName(), // TODO: fix this
Stdin: ctx.Stdin,
Stdout: ctx.Stdout,
Stderr: ctx.Stderr,
Host: c.Placement.Directive,
Client: client,
Stdin: ctx.Stdin,
Stdout: ctx.Stdout,
Stderr: ctx.Stderr,
}
_, err := manual.ProvisionMachine(args)
return err
return errors.Trace(err)
}

client, err := getAddMachineAPI(c)
if err != nil {
return err
}
defer client.Close()
if c.Placement != nil && c.Placement.Scope == "env-uuid" {
c.Placement.Scope = client.EnvironmentUUID()
}
Expand All @@ -156,26 +158,8 @@ func (c *AddMachineCommand) Run(ctx *cmd.Context) error {
}

results, err := client.AddMachines(machines)
if params.IsCodeNotImplemented(err) {
if c.Placement != nil {
containerType, parseErr := instance.ParseContainerType(c.Placement.Scope)
if parseErr != nil {
// The user specified a non-container placement directive:
// return original API not implemented error.
return err
}
machineParams.ContainerType = containerType
machineParams.ParentId = c.Placement.Directive
machineParams.Placement = nil
}
logger.Infof(
"AddMachinesWithPlacement not supported by the API server, " +
"falling back to 1.18 compatibility mode",
)
results, err = client.AddMachines1dot18([]params.AddMachineParams{machineParams})
}
if err != nil {
return err
return errors.Trace(err)
}

errs := []error{}
Expand Down
10 changes: 7 additions & 3 deletions cmd/juju/addmachine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ func (s *AddMachineSuite) TestAddMachineErrors(c *gc.C) {

func (s *AddMachineSuite) TestAddThreeMachinesWithTwoFailures(c *gc.C) {
fakeApi := fakeAddMachineAPI{}
s.PatchValue(&getAddMachineAPI, func(c *AddMachineCommand) (AddMachineAPI, error) {
s.PatchValue(&getAddMachineAPI, func(c *AddMachineCommand) (addMachineAPI, error) {
return &fakeApi, nil
})
fakeApi.successOrder = []bool{true, false, false}
Expand Down Expand Up @@ -209,6 +209,10 @@ func (f *fakeAddMachineAPI) AddMachines(args []params.AddMachineParams) ([]param
}
return results, nil
}
func (f *fakeAddMachineAPI) AddMachines1dot18(args []params.AddMachineParams) ([]params.AddMachinesResult, error) {
return f.AddMachines(args)

func (f *fakeAddMachineAPI) DestroyMachines(machines ...string) error {
return fmt.Errorf("not implemented")
}
func (f *fakeAddMachineAPI) ProvisioningScript(params.ProvisioningScriptParams) (script string, err error) {
return "", fmt.Errorf("not implemented")
}
6 changes: 5 additions & 1 deletion cmd/juju/scp_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,11 @@ func (s *SCPSuite) TestSCPCommand(c *gc.C) {
c.Check(ctx.Stdout.(*bytes.Buffer).String(), gc.Equals, "")
data, err := ioutil.ReadFile(filepath.Join(s.bin, "scp.args"))
c.Check(err, gc.IsNil)
c.Check(string(data), gc.Equals, t.result)
actual := string(data)
if t.proxy {
actual = strings.Replace(actual, ".dns", ".internal", 2)
}
c.Check(actual, gc.Equals, t.result)
}
}
}
Expand Down
Loading

0 comments on commit 88c43de

Please sign in to comment.