func (p *HostService) UpdateById(objectId string, host entity.Host, x_auth_token string) (created bool,
	errorCode string, err error) {
	logrus.Infof("start to update host [%v]", host)
	// do authorize first
	if authorized := GetAuthService().Authorize("update_host", x_auth_token, objectId, p.collectionName); !authorized {
		err = errors.New("required opertion is not authorized!")
		errorCode = COMMON_ERROR_UNAUTHORIZED
		logrus.Errorf("update host with objectId [%v] error is %v", objectId, err)
		return
	}

	if !bson.IsObjectIdHex(objectId) {
		err = errors.New("invalide ObjectId.")
		errorCode = COMMON_ERROR_INVALIDATE
		return
	}

	// FIXING
	//	hostquery, _, _  := p.QueryById(objectId, x_auth_token)
	var selector = bson.M{}
	selector["_id"] = bson.ObjectIdHex(objectId)

	host.ObjectId = bson.ObjectIdHex(objectId)
	host.TimeUpdate = dao.GetCurrentTime()

	logrus.Infof("start to change host")
	err = dao.HandleUpdateByQueryPartial(p.collectionName, selector, &host)
	//	created, err = dao.HandleUpdateOne(&host, dao.QueryStruct{p.collectionName, selector, 0, 0, ""})
	if err != nil {
		logrus.Errorf("update host [%v] error is %v", host, err)
		errorCode = HOST_ERROR_UPDATE
	}
	created = true
	return
}
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 *HostService) Create(host entity.Host, x_auth_token string) (newHost entity.Host,
	errorCode string, err error) {
	logrus.Infof("start to create host [%v]", host)
	// do authorize first
	if authorized := GetAuthService().Authorize("create_host", x_auth_token, "", p.collectionName); !authorized {
		err = errors.New("required opertion is not authorized!")
		errorCode = COMMON_ERROR_UNAUTHORIZED
		logrus.Errorf("create host [%v] error is %v", host, err)
		return
	}

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

	token, err := GetTokenById(x_auth_token)
	if err != nil {
		errorCode = HOST_ERROR_CREATE
		logrus.Errorf("get token failed when create host [%v], error is %v", host, err)
		return
	}

	// set token_id and user_id from token
	host.TenantId = token.Tenant.Id
	host.UserId = token.User.Id

	// set created_time and updated_time
	host.TimeCreate = dao.GetCurrentTime()
	host.TimeUpdate = host.TimeCreate

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

	newHost = host

	return
}
func (p *ClusterService) AddHosts(clusterId, numberStr string, x_auth_token string) (cluster entity.Cluster, errorCode string, err error) {
	logrus.Infof("start to add hosts")
	logrus.Infof("clusterId is %s, number is %s.", clusterId, numberStr)

	// do authorize first
	if authorized := GetAuthService().Authorize("create_host", x_auth_token, clusterId, p.collectionName); !authorized {
		err = errors.New("required opertion is not authorized!")
		errorCode = COMMON_ERROR_UNAUTHORIZED
		logrus.Errorf("authorize failure when adding hosts in cluster with id [%v] , error is %v", clusterId, err)
		return
	}
	if !bson.IsObjectIdHex(clusterId) {
		err = errors.New("Invalid cluster id.")
		errorCode = COMMON_ERROR_INVALIDATE
		return
	}

	var selector = bson.M{}
	selector["_id"] = bson.ObjectIdHex(clusterId)
	cluster = entity.Cluster{}
	err = dao.HandleQueryOne(&cluster, dao.QueryStruct{p.collectionName, selector, 0, 0, ""})
	if err != nil {
		logrus.Errorf("query cluster [objectId=%v] error is %v", clusterId, err)
		errorCode = CLUSTER_ERROR_QUERY
		return
	}

	number, err := strconv.ParseInt(numberStr, 10, 0)
	if err != nil {
		logrus.Errorf("Parse number [objectId=%v] error is %v", numberStr, err)
		errorCode = CLUSTER_ERROR_INVALID_NUMBER
		return
	}

	if number <= 0 {
		//call terminate hosts to do this
		errorCode := CLUSTER_ERROR_INVALID_NUMBER
		err = errors.New("Invalid number, it should be positive")
		return cluster, errorCode, err
	}

	newHosts := []entity.Host{}
	for i := 0; i < int(number); i++ {
		host := entity.Host{}
		host.ClusterId = clusterId
		host.ClusterName = cluster.Name
		host.Status = HOST_STATUS_DEPLOYING
		//insert info to db
		newHost, _, err := GetHostService().Create(host, x_auth_token)
		newHosts = append(newHosts, newHost)
		if err != nil {
			logrus.Errorf("creat host error is %v", err)
		}
	}

	if IsDeploymentEnabled() {
		//call deployment module to add nodes
		go AddNodes(cluster, int(number), newHosts, x_auth_token)
	}

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