Example #1
0
// CreateUser creates a test user in jUsers and a single jMachine document.
func (c *Client) CreateUser(username, groupname string) (*singleUser, error) {
	privateKey, publicKey, err := sshutil.TemporaryKey()
	if err != nil {
		return nil, err
	}

	// cleanup old document
	awsProvider.DB.Run("jUsers", func(c *mgo.Collection) error {
		return c.Remove(bson.M{"username": username})
	})

	awsProvider.DB.Run("jAccounts", func(c *mgo.Collection) error {
		return c.Remove(bson.M{"profile.nickname": username})
	})

	awsProvider.DB.Run("jGroups", func(c *mgo.Collection) error {
		return c.Remove(bson.M{"slug": groupname})
	})

	// jAccounts
	accountId := bson.NewObjectId()
	account := &models.Account{
		Id: accountId,
		Profile: models.AccountProfile{
			Nickname: username,
		},
	}

	if err := awsProvider.DB.Run("jAccounts", func(c *mgo.Collection) error {
		return c.Insert(&account)
	}); err != nil {
		return nil, err
	}

	// jGroups
	groupId := bson.NewObjectId()
	group := &models.Group{
		Id:    groupId,
		Title: groupname,
		Slug:  groupname,
	}

	if err := awsProvider.DB.Run("jGroups", func(c *mgo.Collection) error {
		return c.Insert(&group)
	}); err != nil {
		return nil, err
	}

	// add relation between use and group
	relationship := &models.Relationship{
		Id:         bson.NewObjectId(),
		TargetId:   accountId,
		TargetName: "JAccount",
		SourceId:   groupId,
		SourceName: "JGroup",
		As:         "member",
	}

	if err := awsProvider.DB.Run("relationships", func(c *mgo.Collection) error {
		return c.Insert(&relationship)
	}); err != nil {
		return nil, err
	}

	// jUsers
	userId := bson.NewObjectId()
	user := &models.User{
		ObjectId:      userId,
		Email:         username + "@" + username + ".com",
		LastLoginDate: time.Now().UTC(),
		RegisteredAt:  time.Now().UTC(),
		Name:          username, // bson equivelant is username
		Password:      "******",
		Status:        "confirmed",
		SshKeys: []struct {
			Title string `bson:"title"`
			Key   string `bson:"key"`
		}{
			{Key: publicKey},
		},
	}

	if err := awsProvider.DB.Run("jUsers", func(c *mgo.Collection) error {
		return c.Insert(&user)
	}); err != nil {
		return nil, err
	}

	// jCredentials and jCredentialData
	credentials := map[string][]string{}

	addCredential := func(credProvider string, data map[string]interface{}) error {
		credentialId := bson.NewObjectId()
		identifier := randomID(24)
		credential := &models.Credential{
			Id:         credentialId,
			Provider:   credProvider,
			Identifier: identifier,
			OriginId:   accountId,
		}

		if err := awsProvider.DB.Run("jCredentials", func(c *mgo.Collection) error {
			return c.Insert(&credential)
		}); err != nil {
			return err
		}

		credentialDataId := bson.NewObjectId()
		credentialData := &models.CredentialData{
			Id:         credentialDataId,
			Identifier: identifier,
			OriginId:   accountId,
			Meta:       data,
		}

		if err := awsProvider.DB.Run("jCredentialDatas", func(c *mgo.Collection) error {
			return c.Insert(&credentialData)
		}); err != nil {
			return err
		}

		credRelationship := &models.Relationship{
			Id:         bson.NewObjectId(),
			TargetId:   credentialId,
			TargetName: "JCredential",
			SourceId:   accountId,
			SourceName: "JAccount",
			As:         "owner",
		}

		if err := awsProvider.DB.Run("relationships", func(c *mgo.Collection) error {
			return c.Insert(&credRelationship)
		}); err != nil {
			return err
		}

		credentials[credProvider] = []string{identifier}
		return nil
	}

	err = addCredential("aws", map[string]interface{}{
		"access_key": os.Getenv("KLOUD_TESTACCOUNT_ACCESSKEY"),
		"secret_key": os.Getenv("KLOUD_TESTACCOUNT_SECRETKEY"),
		"region":     c.region(),
	})
	if err != nil {
		return nil, err
	}

	err = addCredential("softlayer", map[string]interface{}{
		"username": os.Getenv("KLOUD_TESTACCOUNT_SLUSERNAME"),
		"api_key":  os.Getenv("KLOUD_TESTACCOUNT_SLAPIKEY"),
	})
	if err != nil {
		return nil, err
	}

	// jComputeStack and jStackTemplates
	stackTemplateId := bson.NewObjectId()
	stackTemplate := &models.StackTemplate{
		Id:          stackTemplateId,
		Credentials: credentials,
	}
	stackTemplate.Template.Content = fmt.Sprintf(terraformTemplate, machineCount, c.instanceType())

	if err := awsProvider.DB.Run("jStackTemplates", func(c *mgo.Collection) error {
		return c.Insert(&stackTemplate)
	}); err != nil {
		return nil, err
	}

	// later we can add more users with "Owner:false" to test sharing capabilities
	users := []models.MachineUser{
		{Id: userId, Sudo: true, Owner: true},
	}

	machineLabels := make([]string, machineCount)
	machineIds := make([]bson.ObjectId, machineCount)

	for i := 0; i < machineCount; i++ {
		label := "example." + strconv.Itoa(i)
		if machineCount == 1 {
			label = "example"
		}

		machineId := bson.NewObjectId()
		machine := &models.Machine{
			ObjectId:  machineId,
			Label:     label,
			Domain:    username + ".dev.koding.io",
			Provider:  c.Provider,
			CreatedAt: time.Now().UTC(),
			Users:     users,
			Meta:      make(bson.M, 0),
			Groups:    make([]models.MachineGroup, 0),
		}

		switch c.Provider {
		case "koding":
			machine.Credential = username
		default:
			// aws, softlayer
			machine.Credential = credentials[c.Provider][0]
		}

		c.updateMeta(machine.Meta)
		machine.Meta["storage_size"] = 3
		machine.Meta["alwaysOn"] = false
		machine.Assignee.InProgress = false
		machine.Assignee.AssignedAt = time.Now().UTC()
		machine.Status.State = machinestate.NotInitialized.String()
		machine.Status.ModifiedAt = time.Now().UTC()

		machineLabels[i] = machine.Label
		machineIds[i] = machine.ObjectId

		if err := awsProvider.DB.Run("jMachines", func(c *mgo.Collection) error {
			return c.Insert(&machine)
		}); err != nil {
			return nil, err
		}
	}

	computeStackId := bson.NewObjectId()
	computeStack := &models.ComputeStack{
		Id:          computeStackId,
		BaseStackId: stackTemplateId,
		Machines:    machineIds,
	}

	if err := awsProvider.DB.Run("jComputeStacks", func(c *mgo.Collection) error {
		return c.Insert(&computeStack)
	}); err != nil {
		return nil, err
	}

	userKite := kite.New("user", "0.0.1")
	confCopy := conf.Copy()
	confCopy.KiteKey = testutil.NewKiteKeyUsername(username).Raw
	confCopy.Username = username
	userKite.Config = confCopy

	kloudQuery := &protocol.KontrolQuery{
		Username:    "******",
		Environment: confCopy.Environment,
		Name:        "kloud",
	}
	kites, err := userKite.GetKites(kloudQuery)
	if err != nil {
		log.Fatal(err)
	}

	// Get the caller
	remote := kites[0]
	if err := remote.Dial(); err != nil {
		log.Fatal(err)
	}

	identifiers := []string{}
	for _, i := range credentials {
		identifiers = append(identifiers, i...)
	}

	return &singleUser{
		MachineIds:      machineIds,
		MachineLabels:   machineLabels,
		StackId:         computeStackId.Hex(),
		StackTemplateId: stackTemplate.Id.Hex(),
		PrivateKey:      privateKey,
		PublicKey:       publicKey,
		AccountId:       accountId,
		Identifiers:     identifiers,
		Remote:          remote,
	}, nil
}
Example #2
0
func CreateUser(opts *UserOptions) (*User, error) {
	username := opts.Username
	groupname := opts.Groupname
	provider := opts.Provider
	template := opts.Template

	privateKey, publicKey, err := sshutil.TemporaryKey()
	if err != nil {
		return nil, err
	}

	labels, err := machineLabels([]byte(template))
	if err != nil {
		return nil, err
	}

	relationExists := true

	// jAccounts
	account, err := modelhelper.GetAccount(username)
	if err == mgo.ErrNotFound {
		relationExists = false

		account = &models.Account{
			Id: bson.NewObjectId(),
			Profile: models.AccountProfile{
				Nickname: username,
			},
		}

		err = modelhelper.CreateAccount(account)
	}
	if err != nil {
		return nil, errors.New("failure looking up jAccounts: " + err.Error())
	}

	// jGroups
	group, err := modelhelper.GetGroup(groupname)
	if err == mgo.ErrNotFound {
		relationExists = false

		group = &models.Group{
			Id:    bson.NewObjectId(),
			Title: groupname,
			Slug:  groupname,
		}

		err = modelhelper.CreateGroup(group)
	}
	if err != nil {
		return nil, errors.New("failure looking up jGroups: " + err.Error())
	}

	if !relationExists {
		// add relation between use and group
		relationship := &models.Relationship{
			Id:         bson.NewObjectId(),
			TargetId:   account.Id,
			TargetName: "JAccount",
			SourceId:   group.Id,
			SourceName: "JGroup",
			As:         "member",
		}

		err := modelhelper.AddRelationship(relationship)
		if err != nil {
			return nil, errors.New("failure insering relationship: " + err.Error())
		}
	}

	// jUsers
	user, err := modelhelper.GetUser(username)
	if err == nil && len(user.SshKeys) != 0 {
		publicKey = user.SshKeys[0].Key
	}
	if err == mgo.ErrNotFound {
		user = &models.User{
			ObjectId:      bson.NewObjectId(),
			Email:         username + "@" + username + ".com",
			LastLoginDate: time.Now().UTC(),
			RegisteredAt:  time.Now().UTC(),
			Name:          username, // bson equivelant is username
			Password:      "******",
			Status:        "confirmed",
			SshKeys: []struct {
				Title string `bson:"title"`
				Key   string `bson:"key"`
			}{
				{Key: publicKey},
			},
		}

		err = modelhelper.CreateUser(user)
	}
	if err != nil {
		return nil, errors.New("failure looking up jUsers: " + err.Error())
	}

	queryString := protocol.Kite{ID: opts.KlientID}.String()

	cred := &models.Credential{
		Id:         bson.NewObjectId(),
		Provider:   opts.Provider,
		Identifier: bson.NewObjectId().Hex(),
		OriginId:   account.Id,
	}

	credData := &models.CredentialData{
		Id:         bson.NewObjectId(),
		Identifier: cred.Identifier,
		OriginId:   account.Id,
		Meta: bson.M{
			"queryString": queryString,
			"memory":      0,
			"cpu":         0,
			"box":         "",
		},
	}

	if err := modelhelper.InsertCredential(cred, credData); err != nil {
		return nil, err
	}

	relationship := &models.Relationship{
		Id:         bson.NewObjectId(),
		TargetId:   cred.Id,
		TargetName: "JCredential",
		SourceId:   account.Id,
		SourceName: "JAccount",
		As:         "owner",
	}

	if err := modelhelper.AddRelationship(relationship); err != nil {
		return nil, err
	}

	// jComputeStack and jStackTemplates
	stackTemplateId := bson.NewObjectId()
	stackTemplate := &models.StackTemplate{
		Id: stackTemplateId,
		Credentials: map[string][]string{
			"vagrant": {cred.Identifier},
		},
	}
	stackTemplate.Template.Content = template

	if err := modelhelper.CreateStackTemplate(stackTemplate); err != nil {
		return nil, err
	}

	// later we can add more users with "Owner:false" to test sharing capabilities
	users := []models.MachineUser{
		{Id: user.ObjectId, Sudo: true, Owner: true},
	}

	machineIds := make([]bson.ObjectId, len(labels))

	for i, label := range labels {
		machineId := bson.NewObjectId()
		machine := &models.Machine{
			ObjectId:   machineId,
			Label:      label,
			Domain:     username + ".dev.koding.io",
			Provider:   provider,
			CreatedAt:  time.Now().UTC(),
			Users:      users,
			Meta:       make(bson.M, 0),
			Groups:     make([]models.MachineGroup, 0),
			Credential: username,
		}

		machine.Assignee.InProgress = false
		machine.Assignee.AssignedAt = time.Now().UTC()
		machine.Status.State = machinestate.NotInitialized.String()
		machine.Status.ModifiedAt = time.Now().UTC()

		machineIds[i] = machine.ObjectId

		if err := modelhelper.CreateMachine(machine); err != nil {
			return nil, err
		}
	}

	computeStackID := bson.NewObjectId()
	computeStack := &models.ComputeStack{
		Id:          computeStackID,
		BaseStackId: stackTemplateId,
		Machines:    machineIds,
	}

	if err := modelhelper.CreateComputeStack(computeStack); err != nil {
		return nil, err
	}

	return &User{
		MachineIDs:      machineIds,
		MachineLabels:   labels,
		StackID:         computeStackID.Hex(),
		StackTemplateID: stackTemplate.Id.Hex(),
		AccountID:       account.Id,
		CredID:          cred.Id.Hex(),
		CredDataID:      credData.Id.Hex(),
		PrivateKey:      privateKey,
		PublicKey:       publicKey,
		Identifiers:     []string{cred.Identifier},
	}, nil
}