Beispiel #1
0
func (s *apiclientSuite) TestOpenHonorsEnvironTag(c *gc.C) {
	info := s.APIInfo(c)

	// TODO(jam): 2014-06-05 http://pad.lv/1326802
	// we want to test this eventually, but for now s.APIInfo uses
	// conn.StateInfo() which doesn't know about EnvironTag.
	// c.Check(info.EnvironTag, gc.Equals, env.Tag())
	// c.Assert(info.EnvironTag, gc.Not(gc.Equals), "")

	// We start by ensuring we have an invalid tag, and Open should fail.
	info.EnvironTag = names.NewEnvironTag("bad-tag")
	_, err := api.Open(info, api.DialOpts{})
	c.Check(err, gc.ErrorMatches, `unknown environment: "bad-tag"`)
	c.Check(params.ErrCode(err), gc.Equals, params.CodeNotFound)

	// Now set it to the right tag, and we should succeed.
	info.EnvironTag = s.State.EnvironTag()
	st, err := api.Open(info, api.DialOpts{})
	c.Assert(err, jc.ErrorIsNil)
	st.Close()

	// Backwards compatibility, we should succeed if we do not set an
	// environ tag
	info.EnvironTag = names.NewEnvironTag("")
	st, err = api.Open(info, api.DialOpts{})
	c.Assert(err, jc.ErrorIsNil)
	st.Close()
}
Beispiel #2
0
func (s *PresenceSuite) setup(c *gc.C, key string) (*presence.Watcher, *presence.Pinger, <-chan presence.Change) {
	uuid, err := utils.NewUUID()
	c.Assert(err, jc.ErrorIsNil)
	envUUID := uuid.String()

	w := presence.NewWatcher(s.presence, names.NewEnvironTag(envUUID))
	p := presence.NewPinger(s.presence, names.NewEnvironTag(envUUID), key)

	ch := make(chan presence.Change)
	w.Watch(key, ch)
	assertChange(c, ch, presence.Change{key, false})
	return w, p, ch
}
Beispiel #3
0
// NewAPIAuthenticator gets the state and api info once from the
// provisioner API.
func NewAPIAuthenticator(st *apiprovisioner.State) (AuthenticationProvider, error) {
	stateAddresses, err := st.StateAddresses()
	if err != nil {
		return nil, errors.Trace(err)
	}
	apiAddresses, err := st.APIAddresses()
	if err != nil {
		return nil, errors.Trace(err)
	}
	caCert, err := st.CACert()
	if err != nil {
		return nil, errors.Trace(err)
	}
	envUUID, err := st.EnvironUUID()
	if err != nil {
		return nil, errors.Trace(err)
	}
	stateInfo := &mongo.MongoInfo{
		Info: mongo.Info{
			Addrs:  stateAddresses,
			CACert: caCert,
		},
	}
	apiInfo := &api.Info{
		Addrs:      apiAddresses,
		CACert:     caCert,
		EnvironTag: names.NewEnvironTag(envUUID),
	}
	return &simpleAuth{stateInfo, apiInfo}, nil
}
Beispiel #4
0
// EnvironmentsForUser returns a list of enviroments that the user
// is able to access.
func (st *State) EnvironmentsForUser(user names.UserTag) ([]*UserEnvironment, error) {
	// Since there are no groups at this stage, the simplest way to get all
	// the environments that a particular user can see is to look through the
	// environment user collection. A raw collection is required to support
	// queries across multiple environments.
	envUsers, userCloser := st.getRawCollection(envUsersC)
	defer userCloser()

	// TODO: consider adding an index to the envUsers collection on the username.
	var userSlice []envUserDoc
	err := envUsers.Find(bson.D{{"user", user.Username()}}).All(&userSlice)
	if err != nil {
		return nil, err
	}

	var result []*UserEnvironment
	for _, doc := range userSlice {
		envTag := names.NewEnvironTag(doc.EnvUUID)
		env, err := st.GetEnvironment(envTag)
		if err != nil {
			return nil, errors.Trace(err)
		}
		result = append(result, &UserEnvironment{Environment: env, LastConnection: doc.LastConnection})
	}

	return result, nil
}
Beispiel #5
0
func (s *PresenceSuite) SetUpSuite(c *gc.C) {
	s.BaseSuite.SetUpSuite(c)
	s.MgoSuite.SetUpSuite(c)
	uuid, err := utils.NewUUID()
	c.Assert(err, jc.ErrorIsNil)
	s.envTag = names.NewEnvironTag(uuid.String())
}
Beispiel #6
0
// AddLeadsershipSettingsDocs creates service leadership documents in
// the settings collection for all services in all environments.
func AddLeadershipSettingsDocs(st *State) error {
	environments, closer := st.getCollection(environmentsC)
	defer closer()

	var envDocs []bson.M
	err := environments.Find(nil).Select(bson.M{"_id": 1}).All(&envDocs)
	if err != nil {
		return errors.Annotate(err, "failed to read environments")
	}

	for _, envDoc := range envDocs {
		envUUID := envDoc["_id"].(string)
		envSt, err := st.ForEnviron(names.NewEnvironTag(envUUID))
		if err != nil {
			return errors.Annotatef(err, "failed to open environment %q", envUUID)
		}
		defer envSt.Close()

		services, err := envSt.AllServices()
		if err != nil {
			return errors.Annotatef(err, "failed to retrieve services for environment %q", envUUID)
		}

		for _, service := range services {
			// The error from this is intentionally ignored as the
			// transaction will fail if the service already has a
			// leadership settings doc.
			envSt.runTransaction([]txn.Op{
				addLeadershipSettingsOp(service.Name()),
			})
		}
	}
	return nil
}
Beispiel #7
0
// apiInfoConnect looks for endpoint on the given environment and
// tries to connect to it, sending the result on the returned channel.
func apiInfoConnect(info configstore.EnvironInfo, apiOpen api.OpenFunc, stop <-chan struct{}, bClient *httpbakery.Client) (api.Connection, error) {
	endpoint := info.APIEndpoint()
	if info == nil || len(endpoint.Addresses) == 0 {
		return nil, &infoConnectError{fmt.Errorf("no cached addresses")}
	}
	logger.Infof("connecting to API addresses: %v", endpoint.Addresses)
	var environTag names.EnvironTag
	if names.IsValidEnvironment(endpoint.EnvironUUID) {
		environTag = names.NewEnvironTag(endpoint.EnvironUUID)
	}

	apiInfo := &api.Info{
		Addrs:      endpoint.Addresses,
		CACert:     endpoint.CACert,
		Tag:        environInfoUserTag(info),
		Password:   info.APICredentials().Password,
		EnvironTag: environTag,
	}
	if apiInfo.Tag == nil {
		apiInfo.UseMacaroons = true
	}

	dialOpts := api.DefaultDialOpts()
	dialOpts.BakeryClient = bClient

	st, err := apiOpen(apiInfo, dialOpts)
	if err != nil {
		return nil, &infoConnectError{err}
	}
	return st, nil
}
Beispiel #8
0
// APIInfo returns an api.Info for the environment. The result is populated
// with addresses and CA certificate, but no tag or password.
func APIInfo(env Environ) (*api.Info, error) {
	instanceIds, err := env.StateServerInstances()
	if err != nil {
		return nil, err
	}
	logger.Debugf("StateServerInstances returned: %v", instanceIds)
	addrs, err := waitAnyInstanceAddresses(env, instanceIds)
	if err != nil {
		return nil, err
	}
	config := env.Config()
	cert, hasCert := config.CACert()
	if !hasCert {
		return nil, errors.New("config has no CACert")
	}
	apiPort := config.APIPort()
	apiAddrs := network.HostPortsToStrings(
		network.AddressesWithPort(addrs, apiPort),
	)
	uuid, uuidSet := config.UUID()
	if !uuidSet {
		return nil, errors.New("config has no UUID")
	}
	envTag := names.NewEnvironTag(uuid)
	apiInfo := &api.Info{Addrs: apiAddrs, CACert: cert, EnvironTag: envTag}
	return apiInfo, nil
}
Beispiel #9
0
// AddDefaultBlockDevicesDocs creates block devices documents
// for all existing machines in all environments.
func AddDefaultBlockDevicesDocs(st *State) error {
	environments, closer := st.getCollection(environmentsC)
	defer closer()

	var envDocs []bson.M
	err := environments.Find(nil).Select(bson.M{"_id": 1}).All(&envDocs)
	if err != nil {
		return errors.Annotate(err, "failed to read environments")
	}

	for _, envDoc := range envDocs {
		envUUID := envDoc["_id"].(string)
		envSt, err := st.ForEnviron(names.NewEnvironTag(envUUID))
		if err != nil {
			return errors.Annotatef(err, "failed to open environment %q", envUUID)
		}
		defer envSt.Close()

		machines, err := envSt.AllMachines()
		if err != nil {
			return errors.Annotatef(err, "failed to retrieve machines for environment %q", envUUID)
		}

		for _, machine := range machines {
			// If a txn fails because the doc already exists, that's ok.
			if err := envSt.runTransaction([]txn.Op{
				createMachineBlockDevicesOp(machine.Id()),
			}); err != nil && err != txn.ErrAborted {
				return err
			}
		}
	}
	return nil
}
Beispiel #10
0
// apiInfoConnect looks for endpoint on the given environment and
// tries to connect to it, sending the result on the returned channel.
func apiInfoConnect(store configstore.Storage, info configstore.EnvironInfo, apiOpen apiOpenFunc, stop <-chan struct{}) (apiState, error) {
	endpoint := info.APIEndpoint()
	if info == nil || len(endpoint.Addresses) == 0 {
		return nil, &infoConnectError{fmt.Errorf("no cached addresses")}
	}
	logger.Infof("connecting to API addresses: %v", endpoint.Addresses)
	var environTag names.Tag
	if endpoint.EnvironUUID != "" {
		// Note: we should be validating that EnvironUUID contains a
		// valid UUID.
		environTag = names.NewEnvironTag(endpoint.EnvironUUID)
	}
	username := info.APICredentials().User
	if username == "" {
		username = "******"
	}
	apiInfo := &api.Info{
		Addrs:      endpoint.Addresses,
		CACert:     endpoint.CACert,
		Tag:        names.NewUserTag(username),
		Password:   info.APICredentials().Password,
		EnvironTag: environTag,
	}
	st, err := apiOpen(apiInfo, api.DefaultDialOpts())
	if err != nil {
		return nil, &infoConnectError{err}
	}
	return st, nil
}
Beispiel #11
0
// apiInfoConnect looks for endpoint on the given environment and
// tries to connect to it, sending the result on the returned channel.
func apiInfoConnect(store configstore.Storage, info configstore.EnvironInfo, apiOpen apiOpenFunc, stop <-chan struct{}) (apiState, error) {
	endpoint := info.APIEndpoint()
	if info == nil || len(endpoint.Addresses) == 0 {
		return nil, &infoConnectError{fmt.Errorf("no cached addresses")}
	}
	logger.Infof("connecting to API addresses: %v", endpoint.Addresses)
	var environTag names.EnvironTag
	if names.IsValidEnvironment(endpoint.EnvironUUID) {
		environTag = names.NewEnvironTag(endpoint.EnvironUUID)
	} else {
		// For backwards-compatibility, we have to allow connections
		// with an empty UUID. Login will work for the same reasons.
		logger.Warningf("ignoring invalid API endpoint environment UUID %v", endpoint.EnvironUUID)
	}
	apiInfo := &api.Info{
		Addrs:      endpoint.Addresses,
		CACert:     endpoint.CACert,
		Tag:        environInfoUserTag(info),
		Password:   info.APICredentials().Password,
		EnvironTag: environTag,
	}
	st, err := apiOpen(apiInfo, api.DefaultDialOpts())
	if err != nil {
		return nil, &infoConnectError{err}
	}
	return st, nil
}
Beispiel #12
0
// validateEnvironUUID is the common validator for the various
// apiserver components that need to check for a valid environment
// UUID.  An empty envUUID means that the connection has come in at
// the root of the URL space and refers to the state server
// environment.
//
// It returns the validated environment UUID.
func validateEnvironUUID(args validateArgs) (string, error) {
	ssState := args.statePool.SystemState()
	if args.envUUID == "" {
		// We allow the environUUID to be empty for 2 cases
		// 1) Compatibility with older clients
		// 2) TODO: server a limited API at the root (empty envUUID)
		//    with just the user manager and environment manager
		//    if the connection comes over a sufficiently up to date
		//    login command.
		if args.strict {
			return "", errors.Trace(common.UnknownEnvironmentError(args.envUUID))
		}
		logger.Debugf("validate env uuid: empty envUUID")
		return ssState.EnvironUUID(), nil
	}
	if args.envUUID == ssState.EnvironUUID() {
		logger.Debugf("validate env uuid: state server environment - %s", args.envUUID)
		return args.envUUID, nil
	}
	if args.stateServerEnvOnly {
		return "", errors.Unauthorizedf("requested environment %q is not the state server environment", args.envUUID)
	}
	if !names.IsValidEnvironment(args.envUUID) {
		return "", errors.Trace(common.UnknownEnvironmentError(args.envUUID))
	}
	envTag := names.NewEnvironTag(args.envUUID)
	if _, err := ssState.GetEnvironment(envTag); err != nil {
		return "", errors.Wrap(err, common.UnknownEnvironmentError(args.envUUID))
	}
	logger.Debugf("validate env uuid: %s", args.envUUID)
	return args.envUUID, nil
}
Beispiel #13
0
func (s *systemManagerSuite) TestAllEnvironments(c *gc.C) {
	admin := s.Factory.MakeUser(c, &factory.UserParams{Name: "foobar"})

	s.Factory.MakeEnvironment(c, &factory.EnvParams{
		Name: "owned", Owner: admin.UserTag()}).Close()
	remoteUserTag := names.NewUserTag("user@remote")
	st := s.Factory.MakeEnvironment(c, &factory.EnvParams{
		Name: "user", Owner: remoteUserTag})
	defer st.Close()
	st.AddEnvironmentUser(admin.UserTag(), remoteUserTag, "Foo Bar")

	s.Factory.MakeEnvironment(c, &factory.EnvParams{
		Name: "no-access", Owner: remoteUserTag}).Close()

	response, err := s.systemManager.AllEnvironments()
	c.Assert(err, jc.ErrorIsNil)
	// The results are sorted.
	expected := []string{"dummyenv", "no-access", "owned", "user"}
	var obtained []string
	for _, env := range response.UserEnvironments {
		obtained = append(obtained, env.Name)
		stateEnv, err := s.State.GetEnvironment(names.NewEnvironTag(env.UUID))
		c.Assert(err, jc.ErrorIsNil)
		s.checkEnvironmentMatches(c, env.Environment, stateEnv)
	}
	c.Assert(obtained, jc.DeepEquals, expected)
}
Beispiel #14
0
func (s *apiclientSuite) TestConnectWebsocketToRoot(c *gc.C) {
	info := s.APIInfo(c)
	info.EnvironTag = names.NewEnvironTag("")
	conn, _, err := api.ConnectWebsocket(info, api.DialOpts{})
	c.Assert(err, jc.ErrorIsNil)
	defer conn.Close()
	assertConnAddrForRoot(c, conn, info.Addrs[0])
}
Beispiel #15
0
func (*tagsSuite) TestResourceTagsUUID(c *gc.C) {
	testResourceTags(c, testing.EnvironmentTag, nil, map[string]string{
		"juju-env-uuid": testing.EnvironmentTag.Id(),
	})
	testResourceTags(c, names.NewEnvironTag(""), nil, map[string]string{
		"juju-env-uuid": "",
	})
}
Beispiel #16
0
// InstanceTags returns the minimum set of tags that should be set on a
// machine instance, if the provider supports them.
func InstanceTags(cfg *config.Config, jobs []multiwatcher.MachineJob) map[string]string {
	uuid, _ := cfg.UUID()
	instanceTags := tags.ResourceTags(names.NewEnvironTag(uuid), cfg)
	if multiwatcher.AnyJobNeedsState(jobs...) {
		instanceTags[tags.JujuStateServer] = "true"
	}
	return instanceTags
}
Beispiel #17
0
// Initialize sets up an initial empty state and returns it.
// This needs to be performed only once for a given environment.
// It returns unauthorizedError if access is unauthorized.
func Initialize(info *mongo.MongoInfo, cfg *config.Config, opts mongo.DialOpts, policy Policy) (rst *State, err error) {
	st, err := open(info, opts, policy)
	if err != nil {
		return nil, err
	}
	defer func() {
		if err != nil {
			st.Close()
		}
	}()
	// A valid environment is used as a signal that the
	// state has already been initalized. If this is the case
	// do nothing.
	if _, err := st.Environment(); err == nil {
		return st, nil
	} else if !errors.IsNotFound(err) {
		return nil, err
	}
	logger.Infof("initializing environment")
	if err := checkEnvironConfig(cfg); err != nil {
		return nil, err
	}
	uuid, ok := cfg.UUID()
	if !ok {
		return nil, errors.Errorf("environment uuid was not supplied")
	}
	st.environTag = names.NewEnvironTag(uuid)
	ops := []txn.Op{
		createConstraintsOp(st, environGlobalKey, constraints.Value{}),
		createSettingsOp(st, environGlobalKey, cfg.AllAttrs()),
		createEnvironmentOp(st, cfg.Name(), uuid),
		{
			C:      stateServersC,
			Id:     environGlobalKey,
			Assert: txn.DocMissing,
			Insert: &stateServersDoc{
				EnvUUID: uuid,
			},
		}, {
			C:      stateServersC,
			Id:     apiHostPortsKey,
			Assert: txn.DocMissing,
			Insert: &apiHostPortsDoc{},
		}, {
			C:      stateServersC,
			Id:     stateServingInfoKey,
			Assert: txn.DocMissing,
			Insert: &params.StateServingInfo{},
		},
	}
	if err := st.runTransaction(ops); err == txn.ErrAborted {
		// The config was created in the meantime.
		return st, nil
	} else if err != nil {
		return nil, err
	}
	return st, nil
}
Beispiel #18
0
func (s *commonSuite) TestAuthFuncForTagKind(c *gc.C) {
	// TODO(dimitern): This list of all supported tags and kinds needs
	// to live in juju/names.
	uuid, err := utils.NewUUID()
	c.Assert(err, jc.ErrorIsNil)

	allTags := []names.Tag{
		nil, // invalid tag
		names.NewActionTag(uuid.String()),
		names.NewCharmTag("cs:precise/missing"),
		names.NewEnvironTag(uuid.String()),
		names.NewFilesystemTag("20/20"),
		names.NewLocalUserTag("user"),
		names.NewMachineTag("42"),
		names.NewNetworkTag("public"),
		names.NewRelationTag("wordpress:mysql mysql:db"),
		names.NewServiceTag("wordpress"),
		names.NewSpaceTag("apps"),
		names.NewStorageTag("foo/42"),
		names.NewUnitTag("wordpress/5"),
		names.NewUserTag("joe"),
		names.NewVolumeTag("80/20"),
	}
	for i, allowedTag := range allTags {
		c.Logf("test #%d: allowedTag: %v", i, allowedTag)

		var allowedKind string
		if allowedTag != nil {
			allowedKind = allowedTag.Kind()
		}
		getAuthFunc := common.AuthFuncForTagKind(allowedKind)

		authFunc, err := getAuthFunc()
		if allowedKind == "" {
			c.Check(err, gc.ErrorMatches, "tag kind cannot be empty")
			c.Check(authFunc, gc.IsNil)
			continue
		} else if !c.Check(err, jc.ErrorIsNil) {
			continue
		}

		for j, givenTag := range allTags {
			c.Logf("test #%d.%d: givenTag: %v", i, j, givenTag)

			var givenKind string
			if givenTag != nil {
				givenKind = givenTag.Kind()
			}
			if allowedKind == givenKind {
				c.Check(authFunc(givenTag), jc.IsTrue)
			} else {
				c.Check(authFunc(givenTag), jc.IsFalse)
			}
		}
	}
}
Beispiel #19
0
// resourceGroupName returns the name of the environment's resource group.
func resourceGroupName(cfg *config.Config) string {
	uuid, _ := cfg.UUID()
	// UUID is always available for azure environments, since the (new)
	// provider was introduced after environment UUIDs.
	envTag := names.NewEnvironTag(uuid)
	return fmt.Sprintf(
		"juju-%s-%s", cfg.Name(),
		resourceName(envTag),
	)
}
Beispiel #20
0
func (s *EnvironSuite) TestControllerEnvironment(c *gc.C) {
	env, err := s.State.ControllerEnvironment()
	c.Assert(err, jc.ErrorIsNil)

	expectedTag := names.NewEnvironTag(env.UUID())
	c.Assert(env.Tag(), gc.Equals, expectedTag)
	c.Assert(env.ControllerTag(), gc.Equals, expectedTag)
	c.Assert(env.Name(), gc.Equals, "testenv")
	c.Assert(env.Owner(), gc.Equals, s.Owner)
	c.Assert(env.Life(), gc.Equals, state.Alive)
}
Beispiel #21
0
// storageTags returns the tags that should be set on a volume or filesystem,
// if the provider supports them.
func storageTags(
	storageInstance state.StorageInstance,
	cfg *config.Config,
) (map[string]string, error) {
	uuid, _ := cfg.UUID()
	storageTags := tags.ResourceTags(names.NewEnvironTag(uuid), cfg)
	if storageInstance != nil {
		storageTags[tags.JujuStorageInstance] = storageInstance.Tag().Id()
		storageTags[tags.JujuStorageOwner] = storageInstance.Owner().Id()
	}
	return storageTags, nil
}
Beispiel #22
0
func (s *loginSuite) TestInvalidEnvironment(c *gc.C) {
	info, cleanup := s.setupServerWithValidator(c, nil)
	defer cleanup()

	info.EnvironTag = names.NewEnvironTag("rubbish")
	st, err := api.Open(info, fastDialOpts)
	c.Assert(err, jc.ErrorIsNil)
	defer st.Close()

	adminUser := s.AdminUserTag(c)
	err = st.Login(adminUser, "dummy-secret", "")
	c.Assert(err, gc.ErrorMatches, `unknown environment: "rubbish"`)
}
Beispiel #23
0
func (s *provisionerSuite) TestNewState(c *gc.C) {
	apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
		return nil
	})

	st := storageprovisioner.NewState(apiCaller, names.NewMachineTag("123"))
	c.Assert(st, gc.NotNil)
	st = storageprovisioner.NewState(apiCaller, names.NewEnvironTag("87927ace-9e41-4fd5-8103-1a6fb5ff7eb4"))
	c.Assert(st, gc.NotNil)
	c.Assert(func() {
		storageprovisioner.NewState(apiCaller, names.NewUnitTag("mysql/0"))
	}, gc.PanicMatches, "expected EnvironTag or MachineTag, got names.UnitTag")
}
Beispiel #24
0
func (m *envWorkerManager) envHasChanged(uuid string) error {
	envTag := names.NewEnvironTag(uuid)
	envAlive, err := m.isEnvAlive(envTag)
	if err != nil {
		return errors.Trace(err)
	}
	if envAlive {
		err = m.envIsAlive(envTag)
	} else {
		err = m.envIsDead(envTag)
	}
	return errors.Trace(err)
}
Beispiel #25
0
func (s *clientSuite) TestOpenUsesEnvironUUIDPaths(c *gc.C) {
	info := s.APIInfo(c)
	// Backwards compatibility, passing EnvironTag = "" should just work
	info.EnvironTag = names.NewEnvironTag("")
	apistate, err := api.Open(info, api.DialOpts{})
	c.Assert(err, jc.ErrorIsNil)
	apistate.Close()

	// Passing in the correct environment UUID should also work
	environ, err := s.State.Environment()
	c.Assert(err, jc.ErrorIsNil)
	info.EnvironTag = environ.EnvironTag()
	apistate, err = api.Open(info, api.DialOpts{})
	c.Assert(err, jc.ErrorIsNil)
	apistate.Close()

	// Passing in a bad environment UUID should fail with a known error
	info.EnvironTag = names.NewEnvironTag("dead-beef-123456")
	apistate, err = api.Open(info, api.DialOpts{})
	c.Check(err, gc.ErrorMatches, `unknown environment: "dead-beef-123456"`)
	c.Check(err, jc.Satisfies, params.IsCodeNotFound)
	c.Assert(apistate, gc.IsNil)
}
Beispiel #26
0
func (s *clientSuite) TestConnectStreamRootPath(c *gc.C) {
	s.PatchValue(api.WebsocketDialConfig, echoURL(c))

	// If the server is old, we connect to /path.
	info := s.APIInfo(c)
	info.EnvironTag = names.NewEnvironTag("")
	apistate, err := api.OpenWithVersion(info, api.DialOpts{}, 1)
	c.Assert(err, jc.ErrorIsNil)
	defer apistate.Close()
	reader, err := apistate.ConnectStream("/path", nil)
	c.Assert(err, jc.ErrorIsNil)
	connectURL := connectURLFromReader(c, reader)
	c.Assert(connectURL.Path, gc.Matches, "/path")
}
Beispiel #27
0
func (s *clientSuite) TestDebugLogRootPath(c *gc.C) {
	s.PatchValue(api.WebsocketDialConfig, echoURL(c))

	// If the server is old, we log at "/log"
	info := s.APIInfo(c)
	info.EnvironTag = names.NewEnvironTag("")
	apistate, err := api.OpenWithVersion(info, api.DialOpts{}, 1)
	c.Assert(err, jc.ErrorIsNil)
	defer apistate.Close()
	reader, err := apistate.Client().WatchDebugLog(api.DebugLogParams{})
	c.Assert(err, jc.ErrorIsNil)
	connectURL := connectURLFromReader(c, reader)
	c.Assert(connectURL.Path, gc.Matches, "/log")
}
Beispiel #28
0
func (s *loginSuite) TestNonExistentEnvironment(c *gc.C) {
	info, cleanup := s.setupServerWithValidator(c, nil)
	defer cleanup()

	uuid, err := utils.NewUUID()
	c.Assert(err, jc.ErrorIsNil)
	info.EnvironTag = names.NewEnvironTag(uuid.String())
	st, err := api.Open(info, fastDialOpts)
	c.Assert(err, jc.ErrorIsNil)
	defer st.Close()

	adminUser := s.AdminUserTag(c)
	err = st.Login(adminUser, "dummy-secret", "")
	expectedError := fmt.Sprintf("unknown environment: %q", uuid)
	c.Assert(err, gc.ErrorMatches, expectedError)
}
Beispiel #29
0
func (s *NewAPIClientSuite) TestNoEnvironTagDoesntOverwriteCached(c *gc.C) {
	store := newConfigStore("noconfig", dummyStoreInfo)
	called := 0
	// State returns a new set of APIHostPorts but not a new EnvironTag. We
	// shouldn't override the cached value with environ tag of "".
	expectState := mockedAPIState(mockedHostPort)
	apiOpen := func(apiInfo *api.Info, opts api.DialOpts) (juju.APIState, error) {
		checkCommonAPIInfoAttrs(c, apiInfo, opts)
		c.Check(apiInfo.EnvironTag, gc.Equals, names.NewEnvironTag(fakeUUID))
		called++
		return expectState, nil
	}

	mockStore := &storageWithWriteNotify{store: store}
	st, err := juju.NewAPIFromStore("noconfig", mockStore, apiOpen)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(st, gc.Equals, expectState)
	c.Assert(called, gc.Equals, 1)
	c.Assert(mockStore.written, jc.IsTrue)
	info, err := store.ReadInfo("noconfig")
	c.Assert(err, jc.ErrorIsNil)
	ep := info.APIEndpoint()
	c.Check(ep.Addresses, gc.DeepEquals, []string{
		"0.1.2.3:1234", "[2001:db8::1]:1234",
	})
	c.Check(ep.EnvironUUID, gc.Equals, fakeUUID)

	// Now simulate prefer-ipv6: true
	s.PatchValue(juju.MaybePreferIPv6, func(_ configstore.EnvironInfo) bool {
		return true
	})
	expectState = mockedAPIState(mockedHostPort | mockedPreferIPv6)
	st, err = juju.NewAPIFromStore("noconfig", mockStore, apiOpen)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(st, gc.Equals, expectState)
	c.Assert(called, gc.Equals, 2)
	c.Assert(mockStore.written, jc.IsTrue)
	info, err = store.ReadInfo("noconfig")
	c.Assert(err, jc.ErrorIsNil)
	ep = info.APIEndpoint()
	c.Check(ep.Addresses, gc.DeepEquals, []string{
		"[2001:db8::1]:1234", "0.1.2.3:1234",
	})
	c.Check(ep.EnvironUUID, gc.Equals, fakeUUID)
}
Beispiel #30
0
func (s *firewallerSuite) TestWatchOpenedPorts(c *gc.C) {
	c.Assert(s.resources.Count(), gc.Equals, 0)

	s.openPorts(c)
	expectChanges := []string{
		"0:juju-public",
		"2:juju-public",
	}

	fakeEnvTag := names.NewEnvironTag("deadbeef-deaf-face-feed-0123456789ab")
	args := addFakeEntities(params.Entities{Entities: []params.Entity{
		{Tag: fakeEnvTag.String()},
		{Tag: s.machines[0].Tag().String()},
		{Tag: s.service.Tag().String()},
		{Tag: s.units[0].Tag().String()},
	}})
	result, err := s.firewaller.WatchOpenedPorts(args)
	sort.Strings(result.Results[0].Changes)
	c.Assert(err, jc.ErrorIsNil)
	c.Assert(result, jc.DeepEquals, params.StringsWatchResults{
		Results: []params.StringsWatchResult{
			{Changes: expectChanges, StringsWatcherId: "1"},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
			{Error: apiservertesting.ErrUnauthorized},
		},
	})

	// Verify the resource was registered and stop when done
	c.Assert(s.resources.Count(), gc.Equals, 1)
	c.Assert(result.Results[0].StringsWatcherId, gc.Equals, "1")
	resource := s.resources.Get("1")
	defer statetesting.AssertStop(c, resource)

	// Check that the Watch has consumed the initial event ("returned" in
	// the Watch call)
	wc := statetesting.NewStringsWatcherC(c, s.State, resource.(state.StringsWatcher))
	wc.AssertNoChange()
}