예제 #1
0
func (s *StateSuite) TestEnvironConfigWithAdminSecret(c *C) {
	attrs := map[string]interface{}{
		"name":            "test",
		"type":            "test",
		"authorized-keys": "i-am-a-key",
		"default-series":  "precise",
		"development":     true,
		"admin-secret":    "foo",
		"ca-cert":         testing.CACert,
		"ca-private-key":  "",
	}
	cfg, err := config.New(attrs)
	c.Assert(err, IsNil)
	_, err = state.Initialize(state.TestingStateInfo(), cfg)
	c.Assert(err, ErrorMatches, "admin-secret should never be written to the state")

	delete(attrs, "admin-secret")
	cfg, err = config.New(attrs)
	st, err := state.Initialize(state.TestingStateInfo(), cfg)
	c.Assert(err, IsNil)
	st.Close()

	cfg, err = cfg.Apply(map[string]interface{}{"admin-secret": "foo"})
	err = s.State.SetEnvironConfig(cfg)
	c.Assert(err, ErrorMatches, "admin-secret should never be written to the state")
}
예제 #2
0
func (s *InitializeSuite) SetUpTest(c *C) {
	s.LoggingSuite.SetUpTest(c)
	s.MgoSuite.SetUpTest(c)
	var err error
	s.State, err = state.Open(state.TestingStateInfo(), state.TestingDialOpts())
	c.Assert(err, IsNil)
}
예제 #3
0
func (s *InitializeSuite) TestInitialize(c *C) {
	_, err := s.State.EnvironConfig()
	c.Assert(err, checkers.Satisfies, errors.IsNotFoundError)
	_, err = s.State.Annotator("environment-foo")
	c.Assert(err, checkers.Satisfies, errors.IsNotFoundError)
	_, err = s.State.EnvironConstraints()
	c.Assert(err, checkers.Satisfies, errors.IsNotFoundError)

	cfg := testing.EnvironConfig(c)
	initial := cfg.AllAttrs()
	st, err := state.Initialize(state.TestingStateInfo(), cfg, state.TestingDialOpts())
	c.Assert(err, IsNil)
	c.Assert(st, NotNil)
	err = st.Close()
	c.Assert(err, IsNil)

	cfg, err = s.State.EnvironConfig()
	c.Assert(err, IsNil)
	c.Assert(cfg.AllAttrs(), DeepEquals, initial)
	env, err := s.State.Annotator("environment-" + cfg.Name())
	c.Assert(err, IsNil)
	annotations, err := env.Annotations()
	c.Assert(err, IsNil)
	c.Assert(annotations, HasLen, 0)
	cons, err := s.State.EnvironConstraints()
	c.Assert(err, IsNil)
	c.Assert(cons, DeepEquals, constraints.Value{})
}
예제 #4
0
func (s *StateSuite) TestEnvironConfig(c *C) {
	initial := map[string]interface{}{
		"name":                      "test",
		"type":                      "test",
		"authorized-keys":           "i-am-a-key",
		"default-series":            "precise",
		"development":               true,
		"firewall-mode":             "",
		"admin-secret":              "",
		"ca-cert":                   testing.CACert,
		"ca-private-key":            "",
		"ssl-hostname-verification": true,
	}
	cfg, err := config.New(initial)
	c.Assert(err, IsNil)
	st, err := state.Initialize(state.TestingStateInfo(), cfg)
	c.Assert(err, IsNil)
	st.Close()
	c.Assert(err, IsNil)
	cfg, err = s.State.EnvironConfig()
	c.Assert(err, IsNil)
	current := cfg.AllAttrs()
	c.Assert(current, DeepEquals, initial)

	current["authorized-keys"] = "i-am-a-new-key"
	cfg, err = config.New(current)
	c.Assert(err, IsNil)
	err = s.State.SetEnvironConfig(cfg)
	c.Assert(err, IsNil)
	cfg, err = s.State.EnvironConfig()
	c.Assert(err, IsNil)
	final := cfg.AllAttrs()
	c.Assert(final, DeepEquals, current)
}
예제 #5
0
func (s *StateSuite) TestSetAdminMongoPassword(c *C) {
	// Check that we can SetAdminMongoPassword to nothing when there's
	// no password currently set.
	err := s.State.SetAdminMongoPassword("")
	c.Assert(err, IsNil)

	err = s.State.SetAdminMongoPassword("foo")
	c.Assert(err, IsNil)
	defer s.State.SetAdminMongoPassword("")
	info := state.TestingStateInfo()
	err = tryOpenState(info)
	c.Assert(err, Equals, state.ErrUnauthorized)

	info.Password = "******"
	err = tryOpenState(info)
	c.Assert(err, IsNil)

	err = s.State.SetAdminMongoPassword("")
	c.Assert(err, IsNil)

	// Check that removing the password is idempotent.
	err = s.State.SetAdminMongoPassword("")
	c.Assert(err, IsNil)

	info.Password = ""
	err = tryOpenState(info)
	c.Assert(err, IsNil)
}
예제 #6
0
func (s *StateSuite) TestWatchEnvironConfig(c *C) {
	watcher := s.State.WatchEnvironConfig()
	defer func() {
		c.Assert(watcher.Stop(), IsNil)
	}()
	for i, test := range watchEnvironConfigTests {
		c.Logf("test %d", i)
		change, err := config.New(test)
		c.Assert(err, IsNil)
		if i == 0 {
			st, err := state.Initialize(state.TestingStateInfo(), change)
			c.Assert(err, IsNil)
			st.Close()
		} else {
			err = s.State.SetEnvironConfig(change)
			c.Assert(err, IsNil)
		}
		c.Assert(err, IsNil)
		s.State.StartSync()
		select {
		case got, ok := <-watcher.Changes():
			c.Assert(ok, Equals, true)
			c.Assert(got.AllAttrs(), DeepEquals, change.AllAttrs())
		case <-time.After(500 * time.Millisecond):
			c.Fatalf("did not get change: %#v", test)
		}
	}

	select {
	case got := <-watcher.Changes():
		c.Fatalf("got unexpected change: %#v", got)
	case <-time.After(50 * time.Millisecond):
	}
}
예제 #7
0
func (s *StateSuite) TestDialAgain(c *C) {
	// Ensure idempotent operations on Dial are working fine.
	for i := 0; i < 2; i++ {
		st, err := state.Open(state.TestingStateInfo())
		c.Assert(err, IsNil)
		c.Assert(st.Close(), IsNil)
	}
}
예제 #8
0
func (s *StateSuite) TestDoubleInitialize(c *C) {
	m := map[string]interface{}{
		"type":                      "dummy",
		"name":                      "lisboa",
		"authorized-keys":           "i-am-a-key",
		"default-series":            "precise",
		"development":               true,
		"firewall-mode":             "",
		"admin-secret":              "",
		"ca-cert":                   testing.CACert,
		"ca-private-key":            "",
		"ssl-hostname-verification": true,
	}
	cfg, err := config.New(m)
	c.Assert(err, IsNil)
	st, err := state.Initialize(state.TestingStateInfo(), cfg)
	c.Assert(err, IsNil)
	c.Assert(st, NotNil)
	env1, err := st.EnvironConfig()
	st.Close()

	// initialize again, there should be no error and the
	// environ config should not change.
	m = map[string]interface{}{
		"type":                      "dummy",
		"name":                      "sydney",
		"authorized-keys":           "i-am-not-an-animal",
		"default-series":            "xanadu",
		"development":               false,
		"firewall-mode":             "",
		"admin-secret":              "",
		"ca-cert":                   testing.CACert,
		"ca-private-key":            "",
		"ssl-hostname-verification": false,
	}
	cfg, err = config.New(m)
	c.Assert(err, IsNil)
	st, err = state.Initialize(state.TestingStateInfo(), cfg)
	c.Assert(err, IsNil)
	c.Assert(st, NotNil)
	env2, err := st.EnvironConfig()
	st.Close()

	c.Assert(env1.AllAttrs(), DeepEquals, env2.AllAttrs())
}
예제 #9
0
func testSetMongoPassword(c *C, getEntity func(st *state.State) (entity, error)) {
	info := state.TestingStateInfo()
	st, err := state.Open(info)
	c.Assert(err, IsNil)
	defer st.Close()
	// Turn on fully-authenticated mode.
	err = st.SetAdminMongoPassword("admin-secret")
	c.Assert(err, IsNil)

	// Set the password for the entity
	ent, err := getEntity(st)
	c.Assert(err, IsNil)
	err = ent.SetMongoPassword("foo")
	c.Assert(err, IsNil)

	// Check that we cannot log in with the wrong password.
	info.EntityName = ent.EntityName()
	info.Password = "******"
	err = tryOpenState(info)
	c.Assert(err, Equals, state.ErrUnauthorized)

	// Check that we can log in with the correct password.
	info.Password = "******"
	st1, err := state.Open(info)
	c.Assert(err, IsNil)
	defer st1.Close()

	// Change the password with an entity derived from the newly
	// opened and authenticated state.
	ent, err = getEntity(st)
	c.Assert(err, IsNil)
	err = ent.SetMongoPassword("bar")
	c.Assert(err, IsNil)

	// Check that we cannot log in with the old password.
	info.Password = "******"
	err = tryOpenState(info)
	c.Assert(err, Equals, state.ErrUnauthorized)

	// Check that we can log in with the correct password.
	info.Password = "******"
	err = tryOpenState(info)
	c.Assert(err, IsNil)

	// Check that the administrator can still log in.
	info.EntityName, info.Password = "", "admin-secret"
	err = tryOpenState(info)
	c.Assert(err, IsNil)

	// Remove the admin password so that the test harness can reset the state.
	err = st.SetAdminMongoPassword("")
	c.Assert(err, IsNil)
}
예제 #10
0
func (cs *ConnSuite) SetUpTest(c *C) {
	cs.LoggingSuite.SetUpTest(c)
	cs.MgoSuite.SetUpTest(c)
	cs.charms = cs.MgoSuite.Session.DB("juju").C("charms")
	cs.machines = cs.MgoSuite.Session.DB("juju").C("machines")
	cs.relations = cs.MgoSuite.Session.DB("juju").C("relations")
	cs.services = cs.MgoSuite.Session.DB("juju").C("services")
	cs.units = cs.MgoSuite.Session.DB("juju").C("units")
	var err error
	cs.State, err = state.Open(state.TestingStateInfo())
	c.Assert(err, IsNil)
}
예제 #11
0
func (s *StateSuite) TestOpenWithoutSetMongoPassword(c *C) {
	info := state.TestingStateInfo()
	info.EntityName, info.Password = "******", "bar"
	err := tryOpenState(info)
	c.Assert(err, Equals, state.ErrUnauthorized)

	info.EntityName, info.Password = "******", ""
	err = tryOpenState(info)
	c.Assert(err, Equals, state.ErrUnauthorized)

	info.EntityName, info.Password = "", ""
	err = tryOpenState(info)
	c.Assert(err, IsNil)
}
예제 #12
0
func (s *StateSuite) TestWatchEnvironConfigAfterCreation(c *C) {
	cfg, err := config.New(watchEnvironConfigTests[0])
	c.Assert(err, IsNil)
	st, err := state.Initialize(state.TestingStateInfo(), cfg)
	c.Assert(err, IsNil)
	st.Close()
	s.State.Sync()
	watcher := s.State.WatchEnvironConfig()
	defer watcher.Stop()
	select {
	case got, ok := <-watcher.Changes():
		c.Assert(ok, Equals, true)
		c.Assert(got.AllAttrs(), DeepEquals, cfg.AllAttrs())
	case <-time.After(500 * time.Millisecond):
		c.Fatalf("did not get change")
	}
}
예제 #13
0
func (s *InitializeSuite) TestEnvironConfigWithAdminSecret(c *C) {
	// admin-secret blocks Initialize.
	good := testing.EnvironConfig(c)
	bad, err := good.Apply(map[string]interface{}{"admin-secret": "foo"})

	_, err = state.Initialize(state.TestingStateInfo(), bad, state.TestingDialOpts())
	c.Assert(err, ErrorMatches, "admin-secret should never be written to the state")

	// admin-secret blocks SetEnvironConfig.
	st := state.TestingInitialize(c, good)
	st.Close()
	err = s.State.SetEnvironConfig(bad)
	c.Assert(err, ErrorMatches, "admin-secret should never be written to the state")

	// EnvironConfig remains inviolate.
	cfg, err := s.State.EnvironConfig()
	c.Assert(err, IsNil)
	c.Assert(cfg.AllAttrs(), DeepEquals, good.AllAttrs())
}
예제 #14
0
func (s *InitializeSuite) TestDoubleInitializeConfig(c *C) {
	cfg := testing.EnvironConfig(c)
	initial := cfg.AllAttrs()
	st := state.TestingInitialize(c, cfg)
	st.Close()

	// A second initialize returns an open *State, but ignores its params.
	// TODO(fwereade) I think this is crazy, but it's what we were testing
	// for originally...
	cfg, err := cfg.Apply(map[string]interface{}{"authorized-keys": "something-else"})
	c.Assert(err, IsNil)
	st, err = state.Initialize(state.TestingStateInfo(), cfg, state.TestingDialOpts())
	c.Assert(err, IsNil)
	c.Assert(st, NotNil)
	st.Close()

	cfg, err = s.State.EnvironConfig()
	c.Assert(err, IsNil)
	c.Assert(cfg.AllAttrs(), DeepEquals, initial)
}
예제 #15
0
func (s *StateSuite) TestInitialize(c *C) {
	m := map[string]interface{}{
		"type":                      "dummy",
		"name":                      "lisboa",
		"authorized-keys":           "i-am-a-key",
		"default-series":            "precise",
		"development":               true,
		"firewall-mode":             "",
		"admin-secret":              "",
		"ca-cert":                   testing.CACert,
		"ca-private-key":            "",
		"ssl-hostname-verification": true,
	}
	cfg, err := config.New(m)
	c.Assert(err, IsNil)
	st, err := state.Initialize(state.TestingStateInfo(), cfg)
	c.Assert(err, IsNil)
	c.Assert(st, NotNil)
	defer st.Close()
	env, err := st.EnvironConfig()
	c.Assert(env.AllAttrs(), DeepEquals, m)
}
예제 #16
0
func (s *InitializeSuite) TestEnvironConfigWithoutAgentVersion(c *C) {
	// admin-secret blocks Initialize.
	good := testing.EnvironConfig(c)
	attrs := good.AllAttrs()
	delete(attrs, "agent-version")
	bad, err := config.New(attrs)
	c.Assert(err, IsNil)

	_, err = state.Initialize(state.TestingStateInfo(), bad, state.TestingDialOpts())
	c.Assert(err, ErrorMatches, "agent-version must always be set in state")

	// Bad agent-version blocks SetEnvironConfig.
	st := state.TestingInitialize(c, good)
	st.Close()
	err = s.State.SetEnvironConfig(bad)
	c.Assert(err, ErrorMatches, "agent-version must always be set in state")

	// EnvironConfig remains inviolate.
	cfg, err := s.State.EnvironConfig()
	c.Assert(err, IsNil)
	c.Assert(cfg.AllAttrs(), DeepEquals, good.AllAttrs())
}
예제 #17
0
func (s *StateSuite) TestWatchEnvironConfigInvalidConfig(c *C) {
	m := map[string]interface{}{
		"type":            "dummy",
		"name":            "lisboa",
		"authorized-keys": "i-am-a-key",
		"ca-cert":         testing.CACert,
		"ca-private-key":  "",
	}
	cfg1, err := config.New(m)
	c.Assert(err, IsNil)
	st, err := state.Initialize(state.TestingStateInfo(), cfg1)
	c.Assert(err, IsNil)
	st.Close()

	// Corrupt the environment configuration.
	settings := s.Session.DB("juju").C("settings")
	err = settings.UpdateId("e", bson.D{{"$unset", bson.D{{"name", 1}}}})
	c.Assert(err, IsNil)

	s.State.Sync()

	// Start watching the configuration.
	watcher := s.State.WatchEnvironConfig()
	defer watcher.Stop()
	done := make(chan *config.Config)
	go func() {
		select {
		case cfg, ok := <-watcher.Changes():
			if !ok {
				c.Errorf("watcher channel closed")
			} else {
				done <- cfg
			}
		case <-time.After(5 * time.Second):
			c.Fatalf("no environment configuration observed")
		}
	}()

	s.State.Sync()

	// The invalid configuration must not have been generated.
	select {
	case <-done:
		c.Fatalf("configuration returned too soon")
	case <-time.After(100 * time.Millisecond):
	}

	// Fix the configuration.
	cfg2, err := config.New(map[string]interface{}{
		"type":            "dummy",
		"name":            "lisboa",
		"authorized-keys": "new-key",
		"ca-cert":         testing.CACert,
		"ca-private-key":  "",
	})
	c.Assert(err, IsNil)
	err = s.State.SetEnvironConfig(cfg2)
	c.Assert(err, IsNil)

	s.State.StartSync()
	select {
	case cfg3 := <-done:
		c.Assert(cfg3.AllAttrs(), DeepEquals, cfg2.AllAttrs())
	case <-time.After(5 * time.Second):
		c.Fatalf("no environment configuration observed")
	}
}
예제 #18
0
func (s *UnitSuite) TestSetMongoPasswordOnUnitAfterConnectingAsMachineEntity(c *C) {
	// Make a second unit to use later. (Subordinate units can only be created
	// as a side-effect of a principal entering relation scope.)
	subCharm := s.AddTestingCharm(c, "logging")
	_, err := s.State.AddService("logging", subCharm)
	c.Assert(err, IsNil)
	eps, err := s.State.InferEndpoints([]string{"wordpress", "logging"})
	c.Assert(err, IsNil)
	rel, err := s.State.AddRelation(eps...)
	c.Assert(err, IsNil)
	ru, err := rel.Unit(s.unit)
	c.Assert(err, IsNil)
	err = ru.EnterScope(nil)
	c.Assert(err, IsNil)
	subUnit, err := s.State.Unit("logging/0")
	c.Assert(err, IsNil)

	info := state.TestingStateInfo()
	st, err := state.Open(info, state.TestingDialOpts())
	c.Assert(err, IsNil)
	defer st.Close()
	// Turn on fully-authenticated mode.
	err = st.SetAdminMongoPassword("admin-secret")
	c.Assert(err, IsNil)

	// Add a new machine, assign the units to it
	// and set its password.
	m, err := st.AddMachine("series", state.JobHostUnits)
	c.Assert(err, IsNil)
	unit, err := st.Unit(s.unit.Name())
	c.Assert(err, IsNil)
	subUnit, err = st.Unit(subUnit.Name())
	c.Assert(err, IsNil)
	err = unit.AssignToMachine(m)
	c.Assert(err, IsNil)
	err = m.SetMongoPassword("foo")
	c.Assert(err, IsNil)

	// Sanity check that we cannot connect with the wrong
	// password
	info.Tag = m.Tag()
	info.Password = "******"
	err = tryOpenState(info)
	c.Assert(err, checkers.Satisfies, errors.IsUnauthorizedError)

	// Connect as the machine entity.
	info.Tag = m.Tag()
	info.Password = "******"
	st1, err := state.Open(info, state.TestingDialOpts())
	c.Assert(err, IsNil)
	defer st1.Close()

	// Change the password for a unit derived from
	// the machine entity's state.
	unit, err = st1.Unit(s.unit.Name())
	c.Assert(err, IsNil)
	err = unit.SetMongoPassword("bar")
	c.Assert(err, IsNil)

	// Now connect as the unit entity and, as that
	// that entity, change the password for a new unit.
	info.Tag = unit.Tag()
	info.Password = "******"
	st2, err := state.Open(info, state.TestingDialOpts())
	c.Assert(err, IsNil)
	defer st2.Close()

	// Check that we can set its password.
	unit, err = st2.Unit(subUnit.Name())
	c.Assert(err, IsNil)
	err = unit.SetMongoPassword("bar2")
	c.Assert(err, IsNil)

	// Clear the admin password, so tests can reset the db.
	err = st.SetAdminMongoPassword("")
	c.Assert(err, IsNil)
}
예제 #19
0
func (s *StateSuite) TestStateInfo(c *C) {
	info := state.TestingStateInfo()
	c.Assert(s.State.Addrs(), DeepEquals, info.Addrs)
	c.Assert(s.State.CACert(), DeepEquals, info.CACert)
}