func (p *ClusterService) CreateUserCluster(cluster entity.Cluster, x_auth_token string) (newCluster *entity.Cluster,
	errorCode string, err error) {

	// generate ObjectId
	cluster.ObjectId = bson.NewObjectId()

	userId := cluster.UserId
	if len(userId) == 0 {
		err = errors.New("user_id not provided")
		errorCode = COMMON_ERROR_INVALIDATE
		logrus.Errorf("create cluster [%v] error is %v", cluster, err)
		return
	}

	user, err := GetUserById(userId, x_auth_token)
	if err != nil {
		logrus.Errorf("get user by id err is %v", err)
		errorCode = CLUSTER_ERROR_CALL_USERMGMT
		return nil, errorCode, err
	}
	cluster.TenantId = user.TenantId
	cluster.Owner = user.Username

	// set created_time and updated_time
	cluster.TimeCreate = dao.GetCurrentTime()
	cluster.TimeUpdate = cluster.TimeCreate
	cluster.Status = CLUSTER_STATUS_DEPLOYING
	// insert bson to mongodb
	err = dao.HandleInsert(p.collectionName, cluster)
	if err != nil {
		errorCode = CLUSTER_ERROR_CALL_MONGODB
		logrus.Errorf("create cluster [%v] to bson error is %v", cluster, err)
		return
	}

	//add records of hosts in db
	for i := 0; i < cluster.Instances; i++ {
		host := entity.Host{}
		host.ClusterId = cluster.ObjectId.Hex()
		host.ClusterName = cluster.Name
		host.Status = HOST_STATUS_DEPLOYING
		host.UserId = cluster.UserId
		host.TimeCreate = dao.GetCurrentTime()
		host.TimeUpdate = host.TimeCreate

		_, _, err := GetHostService().Create(host, x_auth_token)
		if err != nil {
			logrus.Errorf("insert host to db error is [%v]", err)
		}
	}

	if IsDeploymentEnabled() {
		//call deployment
		go CreateCluster(cluster, x_auth_token)
	}

	newCluster = &cluster
	return
}
func (p *ClusterService) Create(cluster entity.Cluster, x_auth_token string) (newCluster *entity.Cluster,
	errorCode string, err error) {
	logrus.Infof("start to create cluster [%v]", cluster)

	// do authorize first
	if authorized := GetAuthService().Authorize("create_cluster", x_auth_token, "", p.collectionName); !authorized {
		err = errors.New("required opertion is not authorized!")
		errorCode = COMMON_ERROR_UNAUTHORIZED
		logrus.Errorf("create cluster [%v] error is %v", cluster, err)
		return
	}

	//check cluster name
	if !IsClusterNameValid(cluster.Name) {
		return nil, CLUSTER_ERROR_INVALID_NAME, errors.New("Invalid cluster name.")
	}

	//check userId(must be a objectId at least)
	if !bson.IsObjectIdHex(cluster.UserId) {
		logrus.Errorf("invalid userid [%s],not a object id\n", cluster.Name)
		return nil, COMMON_ERROR_INVALIDATE, errors.New("Invalid userid,not a object id")
	}

	//check if cluster name is unique
	ok, errorCode, err := p.isClusterNameUnique(cluster.UserId, cluster.Name)
	if err != nil {
		return nil, errorCode, err
	}
	if !ok {
		logrus.Errorf("clustername [%s] already exist for user with id [%s]\n", cluster.Name, cluster.UserId)
		return nil, CLUSTER_ERROR_NAME_EXIST, errors.New("Conflict clustername")
	}

	//check instances count
	if cluster.Instances < 5 {
		return nil, CLUSTER_ERROR_INVALID_NUMBER, errors.New("Invalid cluster instances, 5 at least")
	}

	//set cluster type to default
	if cluster.Type == "" {
		cluster.Type = "user"
	}
	if cluster.Type == "user" {
		return p.CreateUserCluster(cluster, x_auth_token)
	} else if cluster.Type == "mgmt" {
		return p.CreateMgmtCluster(cluster, x_auth_token)
	} else {
		return nil, CLUSTER_ERROR_INVALID_TYPE, errors.New("unsupport cluster type, user|mgmt expected")
	}

}
func (p *ClusterService) CreateMgmtCluster(cluster entity.Cluster, x_auth_token string) (newCluster *entity.Cluster,
	errorCode string, err error) {
	//check if mgmt cluster already exist
	//only 1 allowed in database
	query := bson.M{}
	query["type"] = "mgmt"
	n, _, _, err := p.queryByQuery(query, 0, 0, "", x_auth_token, false)
	if n > 0 {
		return nil, CLUSTER_ERROR_CALL_MONGODB, errors.New("mgmt cluster already exist")
	}

	if cluster.Name == "" {
		cluster.Name = "Management"
	}
	token, err := GetTokenById(x_auth_token)
	if err != nil {
		logrus.Errorf("get token by id error is %v", err)
		errorCode = CLUSTER_ERROR_CALL_USERMGMT
		return nil, errorCode, err
	}
	if cluster.UserId == "" {
		cluster.UserId = token.User.Id
	}
	if cluster.Owner == "" {
		cluster.Owner = token.User.Username
	}
	if cluster.Details == "" {
		cluster.Details = "Cluster to manage other clusters"
	}
	cluster.TimeCreate = dao.GetCurrentTime()
	cluster.TimeUpdate = cluster.TimeCreate

	cluster.Status = CLUSTER_STATUS_DEPLOYING

	// insert bson to mongodb
	err = dao.HandleInsert(p.collectionName, cluster)
	if err != nil {
		errorCode = CLUSTER_ERROR_CALL_MONGODB
		logrus.Errorf("create cluster [%v] to bson error is %v", cluster, err)
		return
	}

	for i := 0; i < cluster.Instances; i++ {
		host := entity.Host{}
		host.ClusterId = cluster.ObjectId.Hex()
		host.ClusterName = cluster.Name
		host.Status = HOST_STATUS_DEPLOYING
		host.UserId = cluster.UserId
		host.TimeCreate = dao.GetCurrentTime()
		host.TimeUpdate = host.TimeCreate

		_, _, err := GetHostService().Create(host, x_auth_token)
		if err != nil {
			logrus.Errorf("insert host to db error is [%v]", err)
		}
	}

	newCluster = &cluster

	return
}
Example #4
0
//call dcos deployment module to delete nodes
func DeleteNodes(cluster entity.Cluster, hosts []entity.Host, originStatus map[string]string, x_auth_token string) (err error) {
	// var servers []dcosentity.Server
	servers := []dcosentity.Server{}
	for _, host := range hosts {
		server := dcosentity.Server{}
		server.Hostname = host.HostName
		server.IpAddress = host.IP
		server.PrivateIpAddress = host.PrivateIp
		server.IsMaster = host.IsMasterNode
		server.IsSlave = host.IsSlaveNode
		server.IsSwarmMaster = host.IsSwarmMaster
		server.StoragePath = host.StoragePath

		servers = append(servers, server)
	}

	request := new(dcosentity.DeleteRequest)
	request.UserName = cluster.Owner
	request.ClusterName = cluster.Name
	request.Servers = servers

	var deleted_servers *[]dcosentity.Server
	deleted_servers, err = SendDeleteNodesRequest(request)
	if err != nil {
		logrus.Errorf("send delete nodes requst to dcos deployment error [%v] \n", err)
		logrus.Infoln("rollback hosts status")
		// GetClusterService().UpdateStatusById(cluster.ObjectId.Hex(), CLUSTER_STATUS_RUNNING, x_auth_token)
		for _, host := range hosts {
			preStatus := originStatus[host.ObjectId.Hex()]
			_, _, err := GetHostService().UpdateStatusById(host.ObjectId.Hex(), preStatus, x_auth_token)
			if err != nil {
				logrus.Warnf("rollback host[%v] status to [%v] error [%v]", host.HostName, preStatus, err)
			}
		}

		return
	}

	//send deployment success, may success partially
	var hostnames []string
	for _, server := range *deleted_servers {
		hostnames = append(hostnames, server.Hostname)
	}

	for _, host := range hosts {
		var status string
		if StringInSlice(host.HostName, hostnames) {
			status = HOST_STATUS_TERMINATED
		} else {
			status = HOST_STATUS_FAILED
		}
		//update status
		_, _, err := GetHostService().UpdateStatusById(host.ObjectId.Hex(), status, x_auth_token)
		if err != nil {
			logrus.Errorf("update host status error is [%v]", err)
		}
	}

	//update cluster nodes number and status
	logrus.Infoln("update cluster number and status")
	cluster.Instances = cluster.Instances - len(*deleted_servers)
	cluster.Status = CLUSTER_STATUS_RUNNING
	GetClusterService().UpdateCluster(cluster, x_auth_token)
	// //update cluster status
	// logrus.Infoln("set cluster status to RUNNING")
	// GetClusterService().UpdateStatusById(cluster.ObjectId.Hex(), CLUSTER_STATUS_RUNNING, x_auth_token)
	return
}
Example #5
0
//call dcos deployment module to add nodes
func AddNodes(cluster entity.Cluster, createNumber int, hosts []entity.Host, x_auth_token string) (err error) {
	request := new(dcosentity.AddNodeRequest)
	request.UserName = cluster.Owner
	request.ClusterName = cluster.Name
	request.CreateNumber = createNumber
	request.ExistedNumber = cluster.Instances
	request.ProviderInfo = getProvider(cluster.UserId, x_auth_token)

	//create hosts
	_, currentHosts, _, err := GetHostService().QueryHosts(cluster.ObjectId.Hex(), 0, 0, "unterminated", x_auth_token)
	if err != nil {
		logrus.Errorf("get current hosts by clusterId error %v", err)
		removeAddedNodes(hosts, x_auth_token)
		return err
	}

	request.ConsulServer, request.DnsServers, request.SwarmMaster = getNodeInfo(currentHosts)

	logrus.Debugf("add node request is %v", request)

	//call
	//dcos deployment module returns newly-created nodes info
	var servers *[]dcosentity.Server
	servers, err = SendAddNodesRequest(request)
	if err != nil {
		logrus.Errorf("send request to dcos deploy error is %v", err)
		removeAddedNodes(hosts, x_auth_token)
		return
	}

	ok_count := len(*servers)
	logrus.Infof("try to add %d nodes, %d success", createNumber, ok_count)

	//update newly-created hosts
	for i, server := range *servers {
		host := hosts[i]
		id := host.ObjectId.Hex()
		host.HostName = server.Hostname
		host.Status = HOST_STATUS_RUNNING
		host.IP = server.IpAddress
		host.PrivateIp = server.PrivateIpAddress
		host.IsMasterNode = server.IsMaster
		host.IsSlaveNode = server.IsSlave
		host.IsSwarmMaster = server.IsSwarmMaster
		host.TimeUpdate = dao.GetCurrentTime()
		_, _, err := GetHostService().UpdateById(id, host, x_auth_token)
		if err != nil {
			logrus.Errorf("update host error is [%v] \n", err)
		}
	}

	//update status of failed nodes
	for i := ok_count; i < createNumber; i++ {
		_, _, err := GetHostService().UpdateStatusById(hosts[i].ObjectId.Hex(), HOST_STATUS_FAILED, x_auth_token)
		if err != nil {
			logrus.Errorf("update host error is [%v] \n", err)
		}
	}

	//update cluster nodes number and status
	logrus.Infoln("update cluster number and status")
	cluster.Instances = cluster.Instances + len(hosts)
	cluster.Status = CLUSTER_STATUS_RUNNING
	GetClusterService().UpdateCluster(cluster, x_auth_token)
	// //update cluster status
	// logrus.Infoln("set cluster status to RUNNING")
	// GetClusterService().UpdateStatusById(cluster.ObjectId.Hex(), CLUSTER_STATUS_RUNNING, x_auth_token)
	return
}