// 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 }
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 }