github.com/niedbalski/juju@v0.0.0-20190215020005-8ff100488e47/state/backups/restore_test.go (about)

     1  // Copyright 2014 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  // +build !windows
     5  
     6  package backups
     7  
     8  import (
     9  	"fmt"
    10  	"io"
    11  	"net"
    12  	"os"
    13  	"path"
    14  	"strconv"
    15  	"strings"
    16  
    17  	"github.com/juju/clock/testclock"
    18  	"github.com/juju/replicaset"
    19  	gitjujutesting "github.com/juju/testing"
    20  	jc "github.com/juju/testing/checkers"
    21  	"github.com/juju/utils/ssh"
    22  	gc "gopkg.in/check.v1"
    23  	"gopkg.in/juju/names.v2"
    24  	"gopkg.in/mgo.v2/bson"
    25  
    26  	"github.com/juju/juju/agent"
    27  	"github.com/juju/juju/apiserver/params"
    28  	"github.com/juju/juju/mongo/mongotest"
    29  	"github.com/juju/juju/state"
    30  	statetesting "github.com/juju/juju/state/testing"
    31  	coretesting "github.com/juju/juju/testing"
    32  	jujuversion "github.com/juju/juju/version"
    33  )
    34  
    35  var _ = gc.Suite(&RestoreSuite{})
    36  
    37  type RestoreSuite struct {
    38  	coretesting.BaseSuite
    39  	cwd       string
    40  	testFiles []string
    41  }
    42  
    43  func (r *RestoreSuite) SetUpSuite(c *gc.C) {
    44  	r.BaseSuite.SetUpSuite(c)
    45  }
    46  
    47  func (r *RestoreSuite) SetUpTest(c *gc.C) {
    48  	r.cwd = c.MkDir()
    49  	r.BaseSuite.SetUpTest(c)
    50  }
    51  
    52  func (r *RestoreSuite) TestReplicasetIsReset(c *gc.C) {
    53  	server := &gitjujutesting.MgoInstance{Params: []string{"--replSet", "juju"}}
    54  	err := server.Start(coretesting.Certs)
    55  	c.Assert(err, jc.ErrorIsNil)
    56  	defer server.DestroyWithLog()
    57  	mgoAddr := server.Addr()
    58  	dialInfo := server.DialInfo()
    59  
    60  	var cfg *replicaset.Config
    61  	dialInfo = server.DialInfo()
    62  	dialInfo.Addrs = []string{mgoAddr}
    63  	err = resetReplicaSet(dialInfo, mgoAddr)
    64  
    65  	session, err := server.Dial()
    66  	c.Assert(err, jc.ErrorIsNil)
    67  	defer session.Close()
    68  	cfg, err = replicaset.CurrentConfig(session)
    69  	c.Assert(err, jc.ErrorIsNil)
    70  	c.Assert(cfg.Members, gc.HasLen, 1)
    71  	c.Assert(cfg.Members[0].Address, gc.Equals, mgoAddr)
    72  }
    73  
    74  type backupConfigTests struct {
    75  	yamlFile      io.Reader
    76  	expectedError error
    77  	message       string
    78  }
    79  
    80  func (r *RestoreSuite) TestSetAgentAddressScript(c *gc.C) {
    81  	testServerAddresses := []string{
    82  		"FirstNewControllerAddress:30303",
    83  		"SecondNewControllerAddress:30304",
    84  		"ThirdNewControllerAddress:30305",
    85  		"FourthNewControllerAddress:30306",
    86  		"FiftNewControllerAddress:30307",
    87  		"SixtNewControllerAddress:30308",
    88  	}
    89  	for _, address := range testServerAddresses {
    90  		template := setAgentAddressScript(address, address)
    91  		expectedString := fmt.Sprintf("\t\ts/- .*(:[0-9]+)/- %s\\1/\n", address)
    92  		logger.Infof(fmt.Sprintf("Testing with address %q", address))
    93  		c.Assert(strings.Contains(template, expectedString), gc.Equals, true)
    94  	}
    95  }
    96  
    97  func (r *RestoreSuite) TestNewDialInfo(c *gc.C) {
    98  
    99  	cases := []struct {
   100  		machineTag       string
   101  		apiPassword      string
   102  		oldPassword      string
   103  		expectedPassword string
   104  		expectedUser     string
   105  		expectedError    string
   106  	}{
   107  		{"machine-0",
   108  			"",
   109  			"123456",
   110  			"123456",
   111  			"admin",
   112  			"",
   113  		},
   114  		{"machine-1",
   115  			"123123",
   116  			"",
   117  			"123123",
   118  			"machine-1",
   119  			"",
   120  		},
   121  	}
   122  
   123  	dataDir := path.Join(r.cwd, "dataDir")
   124  	err := os.Mkdir(dataDir, os.FileMode(0755))
   125  	c.Assert(err, jc.ErrorIsNil)
   126  
   127  	logDir := path.Join(r.cwd, "logDir")
   128  	err = os.Mkdir(logDir, os.FileMode(0755))
   129  	c.Assert(err, jc.ErrorIsNil)
   130  	for _, testCase := range cases {
   131  		machineTag, err := names.ParseTag(testCase.machineTag)
   132  		c.Assert(err, jc.ErrorIsNil)
   133  
   134  		configParams := agent.AgentConfigParams{
   135  			Paths: agent.Paths{
   136  				DataDir: dataDir,
   137  				LogDir:  logDir,
   138  			},
   139  			UpgradedToVersion: jujuversion.Current,
   140  			Tag:               machineTag,
   141  			Controller:        coretesting.ControllerTag,
   142  			Model:             coretesting.ModelTag,
   143  			Password:          "placeholder",
   144  			Nonce:             "dummyNonce",
   145  			APIAddresses:      []string{"fakeAPIAddress:12345"},
   146  			CACert:            coretesting.CACert,
   147  		}
   148  		statePort := 12345
   149  		privateAddress := "dummyPrivateAddress"
   150  		servingInfo := params.StateServingInfo{
   151  			APIPort:        1234,
   152  			StatePort:      statePort,
   153  			Cert:           coretesting.CACert,
   154  			CAPrivateKey:   "a ca key",
   155  			PrivateKey:     "a key",
   156  			SharedSecret:   "a secret",
   157  			SystemIdentity: "an identity",
   158  		}
   159  
   160  		conf, err := agent.NewStateMachineConfig(configParams, servingInfo)
   161  		c.Assert(err, jc.ErrorIsNil)
   162  		conf.SetOldPassword(testCase.oldPassword)
   163  		conf.SetPassword(testCase.apiPassword)
   164  
   165  		dialInfo, err := newDialInfo(privateAddress, conf)
   166  		if testCase.expectedError != "" {
   167  			c.Assert(err, gc.ErrorMatches, testCase.expectedError)
   168  		} else {
   169  			c.Assert(err, jc.ErrorIsNil)
   170  			c.Assert(dialInfo.Username, gc.Equals, testCase.expectedUser)
   171  			c.Assert(dialInfo.Password, gc.Equals, testCase.expectedPassword)
   172  			c.Assert(dialInfo.Direct, gc.Equals, true)
   173  			c.Assert(dialInfo.Addrs, gc.DeepEquals, []string{net.JoinHostPort(privateAddress, strconv.Itoa(statePort))})
   174  		}
   175  	}
   176  }
   177  
   178  // TestUpdateMongoEntries has all the testing for this function to avoid creating multiple
   179  // mongo instances.
   180  func (r *RestoreSuite) TestUpdateMongoEntries(c *gc.C) {
   181  	server := &gitjujutesting.MgoInstance{}
   182  	err := server.Start(coretesting.Certs)
   183  	c.Assert(err, jc.ErrorIsNil)
   184  	defer server.DestroyWithLog()
   185  	dialInfo := server.DialInfo()
   186  	mgoAddr := server.Addr()
   187  	dialInfo.Addrs = []string{mgoAddr}
   188  	err = updateMongoEntries("1234", "0", "0", dialInfo)
   189  	c.Assert(err, gc.ErrorMatches, "cannot update machine 0 instance information: not found")
   190  
   191  	session, err := server.Dial()
   192  	c.Assert(err, jc.ErrorIsNil)
   193  	defer session.Close()
   194  
   195  	err = session.DB("juju").C("machines").Insert(bson.M{"machineid": "0", "instanceid": "0"})
   196  	c.Assert(err, jc.ErrorIsNil)
   197  
   198  	query := session.DB("juju").C("machines").Find(bson.M{"machineid": "0", "instanceid": "1234"})
   199  	n, err := query.Count()
   200  	c.Assert(err, jc.ErrorIsNil)
   201  	c.Assert(n, gc.Equals, 0)
   202  
   203  	err = updateMongoEntries("1234", "0", "0", dialInfo)
   204  	c.Assert(err, jc.ErrorIsNil)
   205  
   206  	query = session.DB("juju").C("machines").Find(bson.M{"machineid": "0", "instanceid": "1234"})
   207  	n, err = query.Count()
   208  	c.Assert(err, jc.ErrorIsNil)
   209  	c.Assert(n, gc.Equals, 1)
   210  }
   211  
   212  func (r *RestoreSuite) TestNewConnection(c *gc.C) {
   213  	server := &gitjujutesting.MgoInstance{}
   214  	err := server.Start(coretesting.Certs)
   215  	c.Assert(err, jc.ErrorIsNil)
   216  	defer server.DestroyWithLog()
   217  
   218  	ctlr := statetesting.InitializeWithArgs(c,
   219  		statetesting.InitializeArgs{
   220  			Owner: names.NewLocalUserTag("test-admin"),
   221  			Clock: testclock.NewClock(coretesting.NonZeroTime()),
   222  		})
   223  	st := ctlr.SystemState()
   224  	c.Assert(ctlr.Close(), jc.ErrorIsNil)
   225  
   226  	r.PatchValue(&mongoDefaultDialOpts, mongotest.DialOpts)
   227  	r.PatchValue(&environsGetNewPolicyFunc, func() state.NewPolicyFunc {
   228  		return nil
   229  	})
   230  
   231  	newConnection, err := connectToDB(st.ControllerTag(), names.NewModelTag(st.ModelUUID()), statetesting.NewMongoInfo())
   232  	c.Assert(err, jc.ErrorIsNil)
   233  	c.Assert(newConnection.Close(), jc.ErrorIsNil)
   234  }
   235  
   236  func (r *RestoreSuite) TestRunViaSSH(c *gc.C) {
   237  	var (
   238  		passedAddress string
   239  		passedArgs    []string
   240  		passedOptions *ssh.Options
   241  	)
   242  	fakeSSHCommand := func(address string, args []string, options *ssh.Options) *ssh.Cmd {
   243  		passedAddress = address
   244  		passedArgs = args
   245  		passedOptions = options
   246  		return ssh.Command("", []string{"ls"}, &ssh.Options{})
   247  	}
   248  
   249  	r.PatchValue(&sshCommand, fakeSSHCommand)
   250  	runViaSSH("invalidAddress", "invalidScript")
   251  	c.Assert(passedAddress, gc.Equals, "ubuntu@invalidAddress")
   252  	c.Assert(passedArgs, gc.DeepEquals, []string{"sudo", "-n", "bash", "-c 'invalidScript'"})
   253  
   254  	var expectedOptions ssh.Options
   255  	expectedOptions.SetIdentities("/var/lib/juju/system-identity")
   256  	expectedOptions.SetStrictHostKeyChecking(ssh.StrictHostChecksNo)
   257  	expectedOptions.SetKnownHostsFile(os.DevNull)
   258  	c.Assert(passedOptions, jc.DeepEquals, &expectedOptions)
   259  }