Пример #1
0
// AddNetwork creates a new network with the given params. If a
// network with the same name or provider id already exists in state,
// an error satisfying errors.IsAlreadyExists is returned.
func (st *State) AddNetwork(args NetworkInfo) (n *Network, err error) {
	defer errors.Contextf(&err, "cannot add network %q", args.Name)
	if args.CIDR != "" {
		_, _, err := net.ParseCIDR(args.CIDR)
		if err != nil {
			return nil, err
		}
	}
	if args.Name == "" {
		return nil, fmt.Errorf("name must be not empty")
	}
	if !names.IsValidNetwork(args.Name) {
		return nil, fmt.Errorf("invalid name")
	}
	if args.ProviderId == "" {
		return nil, fmt.Errorf("provider id must be not empty")
	}
	if args.VLANTag < 0 || args.VLANTag > 4094 {
		return nil, fmt.Errorf("invalid VLAN tag %d: must be between 0 and 4094", args.VLANTag)
	}
	doc := newNetworkDoc(args)
	ops := []txn.Op{{
		C:      st.networks.Name,
		Id:     args.Name,
		Assert: txn.DocMissing,
		Insert: doc,
	}}
	err = st.runTransaction(ops)
	switch err {
	case txn.ErrAborted:
		if _, err = st.Network(args.Name); err == nil {
			return nil, errors.AlreadyExistsf("network %q", args.Name)
		} else if err != nil {
			return nil, err
		}
	case nil:
		// We have a unique key restriction on the ProviderId field,
		// which will cause the insert to fail if there is another
		// record with the same provider id in the table. The txn
		// logic does not report insertion errors, so we check that
		// the record has actually been inserted correctly before
		// reporting success.
		if _, err = st.Network(args.Name); err != nil {
			return nil, errors.AlreadyExistsf("network with provider id %q", args.ProviderId)
		}
		return newNetwork(st, doc), nil
	}
	return nil, err
}
Пример #2
0
// CreateSettings is part of the SettingsManager interface.
func (m MemSettings) CreateSettings(key string, settings map[string]interface{}) error {
	if _, ok := m.Settings[key]; ok {
		return errors.AlreadyExistsf("settings with key %q", key)
	}
	m.Settings[key] = settings
	return nil
}
Пример #3
0
// AddModelUser adds a new user to the database.
func (st *State) AddModelUser(spec ModelUserSpec) (*ModelUser, error) {
	// Ensure local user exists in state before adding them as an model user.
	if spec.User.IsLocal() {
		localUser, err := st.User(spec.User)
		if err != nil {
			return nil, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", spec.User.Name()))
		}
		if spec.DisplayName == "" {
			spec.DisplayName = localUser.DisplayName()
		}
	}

	// Ensure local createdBy user exists.
	if spec.CreatedBy.IsLocal() {
		if _, err := st.User(spec.CreatedBy); err != nil {
			return nil, errors.Annotatef(err, "createdBy user %q does not exist locally", spec.CreatedBy.Name())
		}
	}

	modelUUID := st.ModelUUID()
	op := createModelUserOp(modelUUID, spec.User, spec.CreatedBy, spec.DisplayName, spec.ReadOnly)
	err := st.runTransaction([]txn.Op{op})
	if err == txn.ErrAborted {
		err = errors.AlreadyExistsf("model user %q", spec.User.Canonical())
	}
	if err != nil {
		return nil, errors.Trace(err)
	}
	// Re-read from DB to get the multi-env updated values.
	return st.ModelUser(spec.User)
}
Пример #4
0
// UpdateAccount implements AccountUpdater.
func (c *MemStore) UpdateAccount(controllerName, accountName string, details jujuclient.AccountDetails) error {
	if err := jujuclient.ValidateControllerName(controllerName); err != nil {
		return err
	}
	if err := jujuclient.ValidateAccountName(accountName); err != nil {
		return err
	}
	if err := jujuclient.ValidateAccountDetails(details); err != nil {
		return err
	}
	accounts, ok := c.Accounts[controllerName]
	if !ok {
		accounts = &jujuclient.ControllerAccounts{
			Accounts: make(map[string]jujuclient.AccountDetails),
		}
		c.Accounts[controllerName] = accounts
	}
	if len(accounts.Accounts) > 0 {
		if _, ok := accounts.Accounts[accountName]; !ok {
			return errors.AlreadyExistsf(
				"alternative account for controller %s",
				controllerName,
			)
		}
	}
	accounts.Accounts[accountName] = details
	return nil

}
Пример #5
0
func (s *Service) start() error {
	installed, err := s.Installed()
	if err != nil {
		return errors.Trace(err)
	}
	if !installed {
		return errors.NotFoundf("application " + s.Service.Name)
	}
	running, err := s.Running()
	if err != nil {
		return errors.Trace(err)
	}
	if running {
		return errors.AlreadyExistsf("running service %s", s.Service.Name)
	}

	conn, err := s.newConn()
	if err != nil {
		return errors.Trace(err)
	}
	defer conn.Close()

	statusCh := newChan()
	_, err = conn.StartUnit(s.UnitName, "fail", statusCh)
	if err != nil {
		return s.errorf(err, "dbus start request failed")
	}

	if err := s.wait("start", statusCh); err != nil {
		return errors.Trace(err)
	}

	return nil
}
Пример #6
0
// Add the named component factory func to the registry.
func RegisterComponentFunc(name string, f ComponentFunc) error {
	if _, ok := registeredComponentFuncs[name]; ok {
		return errors.AlreadyExistsf("%s", name)
	}
	registeredComponentFuncs[name] = f
	return nil
}
Пример #7
0
// Create makes a new Admin account with a given email and pwhash.
func Create(d db.DB, email, pwhash string) (util.Key, error) {
	var none util.Key
	adminJSON, err := db.GetByKey(d, emails, []byte(email))

	switch {
	case err != nil:
		return none, err
	case len(adminJSON) != 0:
		return none, errors.AlreadyExistsf("admin for email %s:", email)
	}

	hash, salt := util.HashedAndSalt(pwhash, time.Now().String())
	seed := time.Now().String()
	key := util.SaltedHash(string(hash), seed)

	adm := &Admin{
		Email: email,
		Salt:  salt,
		Hash:  hash,
		Key:   key,
	}

	if err := db.StoreKeyValue(d, admins, []byte(key), adm); err != nil {
		return none, err
	}

	return key, db.StoreKeyValue(d, emails, []byte(email), adm)
}
Пример #8
0
Файл: charm.go Проект: bac/juju
// AddCharm adds the ch charm with curl to the state.
// On success the newly added charm state is returned.
func (st *State) AddCharm(info CharmInfo) (stch *Charm, err error) {
	charms, closer := st.getCollection(charmsC)
	defer closer()

	if err := validateCharmVersion(info.Charm); err != nil {
		return nil, errors.Trace(err)
	}

	query := charms.FindId(info.ID.String()).Select(bson.D{{"placeholder", 1}})

	buildTxn := func(attempt int) ([]txn.Op, error) {
		var placeholderDoc struct {
			Placeholder bool `bson:"placeholder"`
		}
		if err := query.One(&placeholderDoc); err == mgo.ErrNotFound {

			return insertCharmOps(st, info)
		} else if err != nil {
			return nil, errors.Trace(err)
		} else if placeholderDoc.Placeholder {
			return updateCharmOps(st, info, stillPlaceholder)
		}
		return nil, errors.AlreadyExistsf("charm %q", info.ID)
	}
	if err = st.run(buildTxn); err == nil {
		return st.Charm(info.ID)
	}
	return nil, errors.Trace(err)
}
Пример #9
0
// Track adds records for the payload to persistence. If the payload
// is already there then false gets returned (true if inserted).
// Existing records are not checked for consistency.
func (pp Persistence) Track(id string, pl payload.Payload) (bool, error) {
	logger.Tracef("insertng %#v", pl)

	_, err := pp.LookUp(pl.Name, pl.ID)
	if err == nil {
		return false, errors.AlreadyExistsf("payload for %q", pl.FullID())
	} else if !errors.IsNotFound(err) {
		return false, errors.Annotate(err, "while checking for collisions")
	}
	// TODO(ericsnow) There is a *slight* race here. I haven't found
	// a simple way to check the secondary key in the transaction.

	var okay bool
	var ops []txn.Op
	// TODO(ericsnow) Add unitPersistence.newEnsureAliveOp(pp.unit)?
	ops = append(ops, pp.newInsertPayloadOps(id, pl)...)
	buildTxn := func(attempt int) ([]txn.Op, error) {
		if attempt > 0 {
			okay = false
			return nil, jujutxn.ErrNoOperations
		}
		okay = true
		return ops, nil
	}
	if err := pp.st.Run(buildTxn); err != nil {
		return false, errors.Trace(err)
	}
	return okay, nil
}
Пример #10
0
//Add a queue by name
func (m *Metadata) AddQueue(queue string) error {

	mutex := zk.NewLock(m.zkClient.Conn, m.operationPath, zk.WorldACL(zk.PermAll))
	if err := mutex.Lock(); err != nil {
		return errors.Trace(err)
	}
	defer mutex.Unlock()

	if err := m.RefreshMetadata(); err != nil {
		return errors.Trace(err)
	}

	if exist := m.ExistQueue(queue); exist {
		return errors.AlreadyExistsf("CreateQueue queue:%s ", queue)
	}

	if err := m.manager.CreateTopic(queue, int32(m.config.KafkaReplications),
		int32(m.config.KafkaPartitions)); err != nil {
		return errors.Trace(err)
	}

	path := m.buildQueuePath(queue)
	data := ""
	log.Debugf("add queue, zk path:%s, data:%s", path, data)

	if err := m.zkClient.CreateRec(path, data, 0); err != nil {
		return errors.Trace(err)
	}
	return nil
}
Пример #11
0
func (m *Metadata) AddGroupConfig(group string, queue string,
	write bool, read bool, url string, ips []string) error {

	mutex := zk.NewLock(m.zkClient.Conn, m.operationPath, zk.WorldACL(zk.PermAll))
	if err := mutex.Lock(); err != nil {
		return errors.Trace(err)
	}
	defer mutex.Unlock()

	if err := m.RefreshMetadata(); err != nil {
		return errors.Trace(err)
	}

	if exist := m.ExistGroup(queue, group); exist {
		return errors.AlreadyExistsf("queue : %q, group : %q", queue, group)
	}

	path := m.buildConfigPath(group, queue)
	groupConfig := GroupConfig{
		Group: group,
		Queue: queue,
		Write: write,
		Read:  read,
		Url:   url,
		Ips:   ips,
	}
	data := groupConfig.String()
	log.Debugf("add group config, zk path:%s, data:%s", path, data)
	if err := m.zkClient.CreateRec(path, data, 0); err != nil {
		return errors.Trace(err)
	}
	return nil
}
Пример #12
0
func (i *importer) addSubnet(args SubnetInfo) error {
	buildTxn := func(attempt int) ([]txn.Op, error) {
		subnet, err := i.st.newSubnetFromArgs(args)
		if err != nil {
			return nil, errors.Trace(err)
		}
		ops := i.st.addSubnetOps(args)
		if attempt != 0 {
			if _, err = i.st.Subnet(args.CIDR); err == nil {
				return nil, errors.AlreadyExistsf("subnet %q", args.CIDR)
			}
			if err := subnet.Refresh(); err != nil {
				if errors.IsNotFound(err) {
					return nil, errors.Errorf("ProviderId %q not unique", args.ProviderId)
				}
				return nil, errors.Trace(err)
			}
		}
		return ops, nil
	}
	err := i.st.run(buildTxn)
	if err != nil {
		return errors.Trace(err)
	}
	return nil
}
Пример #13
0
// AddSubnet creates and returns a new subnet
func (st *State) AddSubnet(args SubnetInfo) (subnet *Subnet, err error) {
	defer errors.DeferredAnnotatef(&err, "adding subnet %q", args.CIDR)

	subnet, err = st.newSubnetFromArgs(args)
	if err != nil {
		return nil, errors.Trace(err)
	}
	ops := st.addSubnetOps(args)
	ops = append(ops, assertModelActiveOp(st.ModelUUID()))
	buildTxn := func(attempt int) ([]txn.Op, error) {

		if attempt != 0 {
			if err := checkModelActive(st); err != nil {
				return nil, errors.Trace(err)
			}
			if _, err = st.Subnet(args.CIDR); err == nil {
				return nil, errors.AlreadyExistsf("subnet %q", args.CIDR)
			}
			if err := subnet.Refresh(); err != nil {
				if errors.IsNotFound(err) {
					return nil, errors.Errorf("ProviderId %q not unique", args.ProviderId)
				}
				return nil, errors.Trace(err)
			}
		}
		return ops, nil
	}
	err = st.run(buildTxn)
	if err != nil {
		return nil, errors.Trace(err)
	}
	return subnet, nil
}
Пример #14
0
// AddEnvironmentUser adds a new user to the database.
func (st *State) AddEnvironmentUser(user, createdBy names.UserTag, displayName string) (*EnvironmentUser, error) {
	// Ensure local user exists in state before adding them as an environment user.
	if user.IsLocal() {
		localUser, err := st.User(user)
		if err != nil {
			return nil, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", user.Name()))
		}
		if displayName == "" {
			displayName = localUser.DisplayName()
		}
	}

	// Ensure local createdBy user exists.
	if createdBy.IsLocal() {
		if _, err := st.User(createdBy); err != nil {
			return nil, errors.Annotate(err, fmt.Sprintf("createdBy user %q does not exist locally", createdBy.Name()))
		}
	}

	envuuid := st.EnvironUUID()
	op, doc := createEnvUserOpAndDoc(envuuid, user, createdBy, displayName)
	err := st.runTransaction([]txn.Op{op})
	if err == txn.ErrAborted {
		err = errors.AlreadyExistsf("environment user %q", user.Username())
	}
	if err != nil {
		return nil, errors.Trace(err)
	}
	return &EnvironmentUser{st: st, doc: *doc}, nil
}
Пример #15
0
// NewModel creates a new model with its own UUID and
// prepares it for use. Model and State instances for the new
// model are returned.
//
// The controller model's UUID is attached to the new
// model's document. Having the server UUIDs stored with each
// model document means that we have a way to represent external
// models, perhaps for future use around cross model
// relations.
func (st *State) NewModel(cfg *config.Config, owner names.UserTag) (_ *Model, _ *State, err error) {
	if owner.IsLocal() {
		if _, err := st.User(owner); err != nil {
			return nil, nil, errors.Annotate(err, "cannot create model")
		}
	}

	ssEnv, err := st.ControllerModel()
	if err != nil {
		return nil, nil, errors.Annotate(err, "could not load controller model")
	}

	uuid := cfg.UUID()
	newState, err := st.ForModel(names.NewModelTag(uuid))
	if err != nil {
		return nil, nil, errors.Annotate(err, "could not create state for new model")
	}
	defer func() {
		if err != nil {
			newState.Close()
		}
	}()

	ops, err := newState.envSetupOps(cfg, uuid, ssEnv.UUID(), owner)
	if err != nil {
		return nil, nil, errors.Annotate(err, "failed to create new model")
	}
	err = newState.runTransaction(ops)
	if err == txn.ErrAborted {

		// We have a  unique key restriction on the "owner" and "name" fields,
		// which will cause the insert to fail if there is another record with
		// the same "owner" and "name" in the collection. If the txn is
		// aborted, check if it is due to the unique key restriction.
		models, closer := st.getCollection(modelsC)
		defer closer()
		envCount, countErr := models.Find(bson.D{
			{"owner", owner.Canonical()},
			{"name", cfg.Name()}},
		).Count()
		if countErr != nil {
			err = errors.Trace(countErr)
		} else if envCount > 0 {
			err = errors.AlreadyExistsf("model %q for %s", cfg.Name(), owner.Canonical())
		} else {
			err = errors.New("model already exists")
		}
	}
	if err != nil {
		return nil, nil, errors.Trace(err)
	}

	newEnv, err := newState.Model()
	if err != nil {
		return nil, nil, errors.Trace(err)
	}

	return newEnv, newState, nil
}
Пример #16
0
// RegisterNewCommand will add a command for got to handle when called.
func RegisterNewCommand(name string, constructor CommandConstructor) error {
	existing, ok := registry[name]
	if ok {
		return errors.AlreadyExistsf("command %q already registered for %v", name, existing)
	}
	registry[name] = constructor
	return nil
}
Пример #17
0
Файл: spaces.go Проект: bac/juju
// AddSpace creates and returns a new space.
func (st *State) AddSpace(name string, providerId network.Id, subnets []string, isPublic bool) (newSpace *Space, err error) {
	defer errors.DeferredAnnotatef(&err, "adding space %q", name)
	if !names.IsValidSpace(name) {
		return nil, errors.NewNotValid(nil, "invalid space name")
	}

	spaceDoc := spaceDoc{
		Life:       Alive,
		Name:       name,
		IsPublic:   isPublic,
		ProviderId: string(providerId),
	}
	newSpace = &Space{doc: spaceDoc, st: st}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     name,
		Assert: txn.DocMissing,
		Insert: spaceDoc,
	}}

	if providerId != "" {
		ops = append(ops, st.networkEntityGlobalKeyOp("space", providerId))
	}

	for _, subnetId := range subnets {
		// TODO:(mfoord) once we have refcounting for subnets we should
		// also assert that the refcount is zero as moving the space of a
		// subnet in use is not permitted.
		ops = append(ops, txn.Op{
			C:      subnetsC,
			Id:     subnetId,
			Assert: txn.DocExists,
			Update: bson.D{{"$set", bson.D{{"space-name", name}}}},
		})
	}

	if err := st.runTransaction(ops); err == txn.ErrAborted {
		if _, err := st.Space(name); err == nil {
			return nil, errors.AlreadyExistsf("space %q", name)
		}
		for _, subnetId := range subnets {
			if _, err := st.Subnet(subnetId); errors.IsNotFound(err) {
				return nil, err
			}
		}
		if err := newSpace.Refresh(); err != nil {
			if errors.IsNotFound(err) {
				return nil, errors.Errorf("ProviderId %q not unique", providerId)
			}
			return nil, errors.Trace(err)
		}
		return nil, errors.Trace(err)
	} else if err != nil {
		return nil, err
	}
	return newSpace, nil
}
Пример #18
0
func (s *SpacesSuite) TestAddSpacesAPIError(c *gc.C) {
	apiservertesting.SharedStub.SetErrors(errors.AlreadyExistsf("space-foo"))
	p := checkAddSpacesParams{
		Name:      "foo",
		Subnets:   []string{"10.0.0.0/24"},
		MakesCall: true,
		Error:     "space-foo already exists",
	}
	s.checkAddSpaces(c, p)
}
Пример #19
0
func (m *Metadata) RegisterService(id int, data string) error {
	err := m.zkClient.Create(fmt.Sprintf("%s/%d", m.servicePath, id), data, zk.FlagEphemeral)
	if err != nil {
		if err == zk.ErrNodeExists {
			return errors.AlreadyExistsf("service %d", id)
		}
		return errors.Trace(err)
	}
	return nil
}
Пример #20
0
// addIPAddress implements the State method to add an IP address.
func addIPAddress(st *State, addr network.Address, subnetid string) (ipaddress *IPAddress, err error) {
	defer errors.DeferredAnnotatef(&err, "cannot add IP address %q", addr)

	// This checks for a missing value as well as invalid values
	ip := net.ParseIP(addr.Value)
	if ip == nil {
		return nil, errors.NotValidf("address")
	}

	// Generate the UUID for the new IP address.
	uuid, err := utils.NewUUID()
	if err != nil {
		return nil, err
	}

	addressID := st.docID(addr.Value)
	ipDoc := ipaddressDoc{
		DocID:     addressID,
		ModelUUID: st.ModelUUID(),
		UUID:      uuid.String(),
		Life:      Alive,
		State:     AddressStateUnknown,
		SubnetId:  subnetid,
		Value:     addr.Value,
		Type:      string(addr.Type),
		Scope:     string(addr.Scope),
		SpaceName: string(addr.SpaceName),
	}

	ipaddress = &IPAddress{doc: ipDoc, st: st}
	ops := []txn.Op{
		assertModelAliveOp(st.ModelUUID()),
		{
			C:      ipaddressesC,
			Id:     addressID,
			Assert: txn.DocMissing,
			Insert: ipDoc,
		},
	}

	err = st.runTransaction(ops)
	switch err {
	case txn.ErrAborted:
		if err := checkModeLife(st); err != nil {
			return nil, errors.Trace(err)
		}
		if _, err = st.IPAddress(addr.Value); err == nil {
			return nil, errors.AlreadyExistsf("address")
		}
	case nil:
		return ipaddress, nil
	}
	return nil, errors.Trace(err)
}
Пример #21
0
// addBsonDField adds a new field to the end of a bson.D, returning
// the updated bson.D.
func addBsonDField(d bson.D, name string, value interface{}) (bson.D, error) {
	for i := range d {
		if d[i].Name == name {
			return nil, errors.AlreadyExistsf("field %q", name)
		}
	}
	return append(d, bson.DocElem{
		Name:  name,
		Value: value,
	}), nil
}
Пример #22
0
func (st *State) addUserAccess(spec UserAccessSpec, target userAccessTarget) (permission.UserAccess, error) {
	// Ensure local user exists in state before adding them as an model user.
	if spec.User.IsLocal() {
		localUser, err := st.User(spec.User)
		if err != nil {
			return permission.UserAccess{}, errors.Annotate(err, fmt.Sprintf("user %q does not exist locally", spec.User.Name()))
		}
		if spec.DisplayName == "" {
			spec.DisplayName = localUser.DisplayName()
		}
	}

	// Ensure local createdBy user exists.
	if spec.CreatedBy.IsLocal() {
		if _, err := st.User(spec.CreatedBy); err != nil {
			return permission.UserAccess{}, errors.Annotatef(err, "createdBy user %q does not exist locally", spec.CreatedBy.Name())
		}
	}
	var (
		ops       []txn.Op
		err       error
		targetTag names.Tag
	)
	switch target.globalKey {
	case modelGlobalKey:
		ops = createModelUserOps(
			target.uuid,
			spec.User,
			spec.CreatedBy,
			spec.DisplayName,
			st.NowToTheSecond(),
			spec.Access)
		targetTag = names.NewModelTag(target.uuid)
	case controllerGlobalKey:
		ops = createControllerUserOps(
			st.ControllerUUID(),
			spec.User,
			spec.CreatedBy,
			spec.DisplayName,
			st.NowToTheSecond(),
			spec.Access)
		targetTag = st.controllerTag
	default:
		return permission.UserAccess{}, errors.NotSupportedf("user access global key %q", target.globalKey)
	}
	err = st.runTransactionFor(target.uuid, ops)
	if err == txn.ErrAborted {
		err = errors.AlreadyExistsf("user access %q", spec.User.Id())
	}
	if err != nil {
		return permission.UserAccess{}, errors.Trace(err)
	}
	return st.UserAccess(spec.User, targetTag)
}
Пример #23
0
func (m *Manager) createOrUpdateTopicPartitionAssignmentPathInZK(topic string,
	assignment partitonAssignment, update bool) error {

	topicPath := fmt.Sprintf("%s%s/%s", m.kafkaRoot, brokerTopics, topic)
	if !update {
		exist, _, err := m.zkClient.Exists(topicPath)
		if err != nil {
			return errors.Trace(err)
		}
		if exist {
			return errors.AlreadyExistsf("topic : %q", topic)
		}
		// 由于命令接口前段对queue名称进行了限制,所以暂时不需要下面这几步校验
		//		topics, err := m.client.Topics()
		//		if err != nil {
		//			return errors.Trace(err)
		//		}
		//		for _, noTopic := range topics {
		//			if strings.Replace(topic, ".", "_", -1) == strings.Replace(noTopic, ".", "_", -1) {
		//				return errors.NotValidf("topic : %q", topic)
		//			}
		//		}
		info := &topicInfo{Version: defaultVersion}
		topicConfigPath := fmt.Sprintf("%s%s/%s", m.kafkaRoot, topicConfigs, topic)
		configData, err := json.Marshal(&info)
		if err != nil {
			return errors.Trace(err)
		}
		err = m.zkClient.Create(topicConfigPath, string(configData), 0)
		if err != nil {
			return errors.Trace(err)
		}
	}
	partitionConfig := topicPatitionConfig{
		Version:    defaultVersion,
		Partitions: assignment,
	}
	partitionConfigData, err := json.Marshal(&partitionConfig)
	if err != nil {
		return errors.Trace(err)
	}
	if update {
		err = m.zkClient.Set(topicPath, string(partitionConfigData))
		if err != nil {
			return errors.Trace(err)
		}
	} else {
		err = m.zkClient.Create(topicPath, string(partitionConfigData), 0)
		if err != nil {
			return errors.Trace(err)
		}
	}
	return nil
}
Пример #24
0
Файл: user.go Проект: bac/juju
func (st *State) addUser(name, displayName, password, creator string, secretKey []byte) (*User, error) {
	if !names.IsValidUserName(name) {
		return nil, errors.Errorf("invalid user name %q", name)
	}
	nameToLower := strings.ToLower(name)

	dateCreated := st.NowToTheSecond()
	user := &User{
		st: st,
		doc: userDoc{
			DocID:       nameToLower,
			Name:        name,
			DisplayName: displayName,
			SecretKey:   secretKey,
			CreatedBy:   creator,
			DateCreated: dateCreated,
		},
	}

	if password != "" {
		salt, err := utils.RandomSalt()
		if err != nil {
			return nil, err
		}
		user.doc.PasswordHash = utils.UserPasswordHash(password, salt)
		user.doc.PasswordSalt = salt
	}

	ops := []txn.Op{{
		C:      usersC,
		Id:     nameToLower,
		Assert: txn.DocMissing,
		Insert: &user.doc,
	}}
	controllerUserOps := createControllerUserOps(st.ControllerUUID(),
		names.NewUserTag(name),
		names.NewUserTag(creator),
		displayName,
		dateCreated,
		defaultControllerPermission)
	ops = append(ops, controllerUserOps...)

	err := st.runTransaction(ops)
	if err == txn.ErrAborted {
		err = errors.AlreadyExistsf("user")
	}
	if err != nil {
		return nil, errors.Trace(err)
	}
	return user, nil
}
Пример #25
0
func (s *CreateSuite) TestRunWithExistingSubnetFails(c *gc.C) {
	s.api.SetErrors(nil, errors.AlreadyExistsf("subnet %q", "10.10.0.0/24"))

	err := s.AssertRunFails(c,
		`cannot create subnet "10.10.0.0/24": subnet "10.10.0.0/24" already exists`,
		"10.10.0.0/24", "space", "zone1",
	)
	c.Assert(err, jc.Satisfies, errors.IsAlreadyExists)

	s.api.CheckCallNames(c, "AllZones", "CreateSubnet", "Close")
	s.api.CheckCall(c, 1, "CreateSubnet",
		names.NewSubnetTag("10.10.0.0/24"), names.NewSpaceTag("space"), s.Strings("zone1"), false,
	)
}
Пример #26
0
// UpdateAccount implements AccountUpdater.
func (s *store) UpdateAccount(controllerName, accountName string, details AccountDetails) error {
	if err := ValidateControllerName(controllerName); err != nil {
		return errors.Trace(err)
	}
	if err := ValidateAccountName(accountName); err != nil {
		return errors.Trace(err)
	}
	if err := ValidateAccountDetails(details); err != nil {
		return errors.Trace(err)
	}

	lock, err := s.lock("update-account")
	if err != nil {
		return errors.Trace(err)
	}
	defer s.unlock(lock)

	controllerAccounts, err := ReadAccountsFile(JujuAccountsPath())
	if err != nil {
		return errors.Trace(err)
	}
	if controllerAccounts == nil {
		controllerAccounts = make(map[string]*ControllerAccounts)
	}
	accounts, ok := controllerAccounts[controllerName]
	if !ok {
		accounts = &ControllerAccounts{
			Accounts: make(map[string]AccountDetails),
		}
		controllerAccounts[controllerName] = accounts
	}
	if oldDetails, ok := accounts.Accounts[accountName]; ok && details == oldDetails {
		return nil
	}

	// NOTE(axw) it is currently not valid for a client to have multiple
	// logins for a controller. We may relax this in the future, but for
	// now we are strict.
	if len(accounts.Accounts) > 0 {
		if _, ok := accounts.Accounts[accountName]; !ok {
			return errors.AlreadyExistsf(
				"alternative account for controller %s",
				controllerName,
			)
		}
	}

	accounts.Accounts[accountName] = details
	return errors.Trace(WriteAccountsFile(controllerAccounts))
}
Пример #27
0
Файл: file.go Проект: bac/juju
// AddController implements ControllerUpdater.
func (s *store) AddController(name string, details ControllerDetails) error {
	if err := ValidateControllerName(name); err != nil {
		return errors.Trace(err)
	}
	if err := ValidateControllerDetails(details); err != nil {
		return errors.Trace(err)
	}

	releaser, err := s.acquireLock()
	if err != nil {
		return errors.Annotatef(err, "cannot add controller %v", name)
	}
	defer releaser.Release()

	all, err := ReadControllersFile(JujuControllersPath())
	if err != nil {
		return errors.Annotate(err, "cannot get controllers")
	}

	if len(all.Controllers) == 0 {
		all.Controllers = make(map[string]ControllerDetails)
	}

	if _, ok := all.Controllers[name]; ok {
		return errors.AlreadyExistsf("controller with name %s", name)
	}

	for k, v := range all.Controllers {
		if v.ControllerUUID == details.ControllerUUID {
			return errors.AlreadyExistsf("controller with UUID %s (%s)",
				details.ControllerUUID, k)
		}
	}

	all.Controllers[name] = details
	return WriteControllersFile(all)
}
Пример #28
0
// AddSpace creates and returns a new space.
func (st *State) AddSpace(name string, subnets []string, isPublic bool) (newSpace *Space, err error) {
	defer errors.DeferredAnnotatef(&err, "adding space %q", name)
	if !names.IsValidSpace(name) {
		return nil, errors.NewNotValid(nil, "invalid space name")
	}

	spaceID := st.docID(name)
	spaceDoc := spaceDoc{
		DocID:    spaceID,
		EnvUUID:  st.EnvironUUID(),
		Life:     Alive,
		Name:     name,
		IsPublic: isPublic,
	}
	newSpace = &Space{doc: spaceDoc, st: st}

	ops := []txn.Op{{
		C:      spacesC,
		Id:     spaceID,
		Assert: txn.DocMissing,
		Insert: spaceDoc,
	}}

	for _, subnetId := range subnets {
		// TODO:(mfoord) once we have refcounting for subnets we should
		// also assert that the refcount is zero as moving the space of a
		// subnet in use is not permitted.
		ops = append(ops, txn.Op{
			C:      subnetsC,
			Id:     st.docID(subnetId),
			Assert: txn.DocExists,
			Update: bson.D{{"$set", bson.D{{"space-name", name}}}},
		})
	}

	if err := st.runTransaction(ops); err == txn.ErrAborted {
		if _, err := st.Space(name); err == nil {
			return nil, errors.AlreadyExistsf("space %q", name)
		}
		for _, subnetId := range subnets {
			if _, err := st.Subnet(subnetId); errors.IsNotFound(err) {
				return nil, err
			}
		}
	} else if err != nil {
		return nil, err
	}
	return newSpace, nil
}
Пример #29
0
func (s *Service) install() error {
	installed, err := s.Installed()
	if err != nil {
		return errors.Trace(err)
	}
	if installed {
		same, err := s.check()
		if err != nil {
			return errors.Trace(err)
		}
		if same {
			return errors.AlreadyExistsf("service %s", s.Service.Name)
		}
		// An old copy is already running so stop it first.
		if err := s.Stop(); err != nil {
			return errors.Annotate(err, "systemd: could not stop old service")
		}
		if err := s.Remove(); err != nil {
			return errors.Annotate(err, "systemd: could not remove old service")
		}
	}

	filename, err := s.writeConf()
	if err != nil {
		return errors.Trace(err)
	}

	conn, err := s.newConn()
	if err != nil {
		return errors.Trace(err)
	}
	defer conn.Close()

	runtime, force := false, true
	_, err = conn.LinkUnitFiles([]string{filename}, runtime, force)
	if err != nil {
		return s.errorf(err, "dbus link request failed")
	}

	if err := conn.Reload(); err != nil {
		return s.errorf(err, "dbus post-link daemon reload request failed")
	}

	_, _, err = conn.EnableUnitFiles([]string{filename}, runtime, force)
	if err != nil {
		return s.errorf(err, "dbus enable request failed")
	}
	return nil
}
Пример #30
0
func (s *SpacesSuite) TestAddSpacesAPIError(c *gc.C) {
	apiservertesting.SharedStub.SetErrors(
		nil, // Backing.EnvironConfig()
		nil, // Provider.Open()
		nil, // ZonedNetworkingEnviron.SupportsSpaces()
		errors.AlreadyExistsf("space-foo"), // Backing.AddSpace()
	)
	p := checkAddSpacesParams{
		Name:      "foo",
		Subnets:   []string{"10.0.0.0/24"},
		MakesCall: true,
		Error:     "space-foo already exists",
	}
	s.checkAddSpaces(c, p)
}