예제 #1
0
func postImageInformationCreate(request *restful.Request, response *restful.Response) {
	imageInformation := new(image.ImageInformation)
	err := request.ReadEntity(&imageInformation)
	if err != nil {
		jsonMap := make(map[string]interface{})
		jsonMap["Error"] = "Read body failure"
		jsonMap["ErrorMessage"] = err.Error()
		errorMessageByteSlice, _ := json.Marshal(jsonMap)
		log.Error(jsonMap)
		response.WriteErrorString(400, string(errorMessageByteSlice))
		return
	}

	oldImageInformation, _ := image.GetStorage().LoadImageInformation(imageInformation.Name)
	if oldImageInformation != nil {
		jsonMap := make(map[string]interface{})
		jsonMap["Error"] = "Duplicated repository error"
		jsonMap["ErrorMessage"] = "Already exists"
		jsonMap["imageInformation"] = imageInformation
		errorMessageByteSlice, _ := json.Marshal(jsonMap)
		log.Error(jsonMap)
		response.WriteErrorString(401, string(errorMessageByteSlice))
		return
	}

	// Initialize the output file for websocket
	image.TouchOutMessageFile(imageInformation.Name)

	go func() {
		image.BuildCreate(imageInformation)
	}()
	/*
		outputMessage, err := image.BuildCreate(imageInformation)

		resultJsonMap := make(map[string]interface{})
		resultJsonMap["OutputMessage"] = outputMessage
		statusCode := 200
		if err != nil {
			statusCode = 422
			resultJsonMap["Error"] = "Create build failure"
			resultJsonMap["ErrorMessage"] = err.Error()
			resultJsonMap["imageInformation"] = imageInformation
			log.Error(resultJsonMap)
		}
		result, err := json.Marshal(resultJsonMap)
		if err != nil {
			jsonMap := make(map[string]interface{})
			jsonMap["Error"] = "Marshal output message failure"
			jsonMap["ErrorMessage"] = err.Error()
			jsonMap["resultJsonMap"] = resultJsonMap
			errorMessageByteSlice, _ := json.Marshal(jsonMap)
			log.Error(jsonMap)
			response.WriteErrorString(422, string(errorMessageByteSlice))
			return
		}

		response.WriteErrorString(statusCode, string(result))
		return
	*/
}
예제 #2
0
func DeployUpdate(
	kubeApiServerEndPoint string, kubeApiServerToken string, namespace string,
	imageInformationName string, version string, description string,
	environmentSlice []control.ReplicationControllerContainerEnvironment) error {
	if lock.AcquireLock(LockKind, getLockName(namespace, imageInformationName), 0) == false {
		return errors.New("Deployment is controlled by the other command")
	}

	defer lock.ReleaseLock(LockKind, getLockName(namespace, imageInformationName))

	imageRecord, err := image.GetStorage().LoadImageRecord(imageInformationName, version)
	if err != nil {
		log.Error("Load image record error: %s imageInformationName %s version %s", err, imageInformationName, version)
		return err
	}

	// Check whether the image in the private-registry
	privateRegistry, err := registry.GetPrivateRegistryFromPathAndTestAvailable(imageRecord.Path)
	if err != nil {
		log.Error("Get private registry access error: " + err.Error())
		return err
	}
	if privateRegistry.IsImageTagAvailable(imageRecord.ImageInformation, imageRecord.Version) == false {
		return errors.New("The image is not in the private-registry")
	}

	deployInformation, err := GetStorage().LoadDeployInformation(namespace, imageInformationName)
	if err != nil {
		log.Error("Load deploy information error: %s imageInformationName %s version %s", err, imageInformationName, version)
		return err
	}

	oldVersion := deployInformation.CurrentVersion
	deployInformation.CurrentVersion = version
	deployInformation.Description = description

	deployInformation.CurrentVersionDescription = imageRecord.Description

	oldReplicationControllerName := deployInformation.ImageInformationName + oldVersion
	newReplicationControllerName := deployInformation.ImageInformationName + version

	err = control.RollingUpdateReplicationControllerWithSingleContainer(
		kubeApiServerEndPoint, kubeApiServerToken, namespace,
		oldReplicationControllerName, newReplicationControllerName,
		imageRecord.Path, imageRecord.Version, waitingDuration, environmentSlice)
	if err != nil {
		log.Error("Rollingupdate replication controller error: %s", err)
		return err
	}

	err = GetStorage().saveDeployInformation(deployInformation)
	if err != nil {
		log.Error("Save deploy information error: %s", err)
		return err
	}

	return nil
}
예제 #3
0
func getAllImageInformation(request *restful.Request, response *restful.Response) {
	imageInformationSlice, err := image.GetStorage().LoadAllImageInformation()
	if err != nil {
		jsonMap := make(map[string]interface{})
		jsonMap["Error"] = "Get all image information failure"
		jsonMap["ErrorMessage"] = err.Error()
		errorMessageByteSlice, _ := json.Marshal(jsonMap)
		log.Error(jsonMap)
		response.WriteErrorString(422, string(errorMessageByteSlice))
		return
	}

	response.WriteJson(imageInformationSlice, "[]InformationSlice")
}
예제 #4
0
func getImageRecordBelongToImageInformation(request *restful.Request, response *restful.Response) {
	imageInformationName := request.PathParameter("imageinformationname")

	imageRecordSlice, err := image.GetStorage().LoadImageRecordWithImageInformationName(imageInformationName)
	if err != nil {
		jsonMap := make(map[string]interface{})
		jsonMap["Error"] = "Get all image reocrd belonging to the image information failure"
		jsonMap["ErrorMessage"] = err.Error()
		jsonMap["imageInformationName"] = imageInformationName
		errorMessageByteSlice, _ := json.Marshal(jsonMap)
		log.Error(jsonMap)
		response.WriteErrorString(422, string(errorMessageByteSlice))
		return
	}

	response.WriteJson(imageRecordSlice, "[]ImageRecord")
}
예제 #5
0
func Notify(username string, imageInformationName string, signature string, payload string, kubeApiServerEndPoint string, kubeApiServerToken string) error {
	if len(username) == 0 {
		log.Error("User couldn't be empty. Signature %s", signature)
		log.Debug(payload)
		return errors.New("User couldn't be empty")
	}

	if len(signature) == 0 {
		return errors.New("The secret is required")
	}

	user, err := authorization.GetStorage().LoadUser(username)
	etcdError, _ := err.(client.Error)
	if etcdError.Code == client.ErrorCodeKeyNotFound {
		return errors.New("The user " + username + " doesn't exist")
	}
	if err != nil {
		log.Error("Get user error %s. User name %s, signature %s", err, username, signature)
		log.Debug(payload)
		return err
	}

	// If secret is used
	githubWebhookSecret := user.MetaDataMap["githubWebhookSecret"]
	generatedSignature := getGitHashSignature(githubWebhookSecret, payload)
	if generatedSignature != signature {
		log.Error("The signature is invalid. User name %s, signature %s, generated signature %s", username, signature, generatedSignature)
		log.Debug(payload)
		return errors.New("The signature is invalid")
	}

	jsonMap := make(map[string]interface{})
	err = json.Unmarshal([]byte(payload), &jsonMap)
	if err != nil {
		log.Error("Unmarshal payload error %s. User name %s, signature %s", err, username, signature)
		log.Debug(payload)
		return err
	}

	pusherJsonMap, _ := jsonMap["pusher"].(map[string]interface{})
	pusherName, _ := pusherJsonMap["name"].(string)

	repositoryJsonMap, _ := jsonMap["repository"].(map[string]interface{})
	cloneUrl, _ := repositoryJsonMap["clone_url"].(string)

	if len(cloneUrl) == 0 {
		log.Error("Can't find clone_url in github payload. User name %s, signature %s", username, signature)
		log.Debug(payload)
		return errors.New("Can't find clone_url in github payload")
	}

	imageInformation, err := image.GetStorage().LoadImageInformation(imageInformationName)
	etcdError, _ = err.(client.Error)
	if etcdError.Code == client.ErrorCodeKeyNotFound {
		return errors.New("The repository " + imageInformationName + " doesn't exist")
	}
	if err != nil {
		log.Error(err)
		return err
	}

	sourceCodeURL := imageInformation.BuildParameter["sourceCodeURL"]
	if sourceCodeURL != cloneUrl {
		// Not the target, ignore.
		return nil
	}

	if len(imageInformationName) == 0 {
		log.Error("Can't find image information using the github url %s. User name %s, signature %s", cloneUrl, username, signature)
		log.Debug(payload)
		return errors.New("Can't find image information using the github url")
	}

	// Asyncronized build
	go func() {
		outputMessage, err := image.BuildUpgrade(imageInformationName, "Github webhook. Pusher: "+pusherName)
		if err != nil {
			log.Error(err)
			log.Debug(outputMessage)
		} else {
			// Build sccessfully
			// Auto rolling update the deployment if configured
			imageInformation, err := image.GetStorage().LoadImageInformation(imageInformationName)
			if err != nil {
				log.Error(err)
			} else {
				deployInformationSlice, err := deploy.GetDeployInformationWithAutoUpdateForNewBuild(imageInformationName)
				if err != nil {
					log.Error(err)
				} else {
					for _, deployInformation := range deployInformationSlice {
						description := "Trigged by version " + imageInformation.CurrentVersion
						err := deploy.DeployUpdate(
							kubeApiServerEndPoint,
							kubeApiServerToken,
							deployInformation.Namespace,
							imageInformation.Name,
							imageInformation.CurrentVersion,
							description,
							deployInformation.EnvironmentSlice)
						if err != nil {
							log.Error(err)
						}
					}
				}
			}
		}
	}()

	return nil
}
예제 #6
0
func putImageInformationUpgrade(request *restful.Request, response *restful.Response) {
	kubeApiServerEndPoint, kubeApiServerToken, err := configuration.GetAvailablekubeApiServerEndPoint()
	if err != nil {
		jsonMap := make(map[string]interface{})
		jsonMap["Error"] = "Get kube apiserver endpoint and token failure"
		jsonMap["ErrorMessage"] = err.Error()
		errorMessageByteSlice, _ := json.Marshal(jsonMap)
		log.Error(jsonMap)
		response.WriteErrorString(404, string(errorMessageByteSlice))
		return
	}

	imageInformationUpgradeInput := new(ImageInformationUpgradeInput)
	err = request.ReadEntity(&imageInformationUpgradeInput)
	if err != nil {
		jsonMap := make(map[string]interface{})
		jsonMap["Error"] = "Read body failure"
		jsonMap["ErrorMessage"] = err.Error()
		errorMessageByteSlice, _ := json.Marshal(jsonMap)
		log.Error(jsonMap)
		response.WriteErrorString(400, string(errorMessageByteSlice))
		return
	}

	if lock.LockAvailable(image.LockKind, imageInformationUpgradeInput.ImageInformationName) == false {
		jsonMap := make(map[string]interface{})
		jsonMap["Error"] = "Duplicated command failure"
		jsonMap["ErrorMessage"] = "Image is under construction"
		errorMessageByteSlice, _ := json.Marshal(jsonMap)
		log.Error(jsonMap)
		response.WriteErrorString(403, string(errorMessageByteSlice))
		return
	}

	// Initialize the output file for websocket
	image.TouchOutMessageFile(imageInformationUpgradeInput.ImageInformationName)

	go func() {
		_, err := image.BuildUpgrade(
			imageInformationUpgradeInput.ImageInformationName,
			imageInformationUpgradeInput.Description)
		if err == nil {
			// Build sccessfully
			// Auto rolling update the deployment if configured
			imageInformation, err := image.GetStorage().LoadImageInformation(imageInformationUpgradeInput.ImageInformationName)
			if err != nil {
				log.Error(err)
			} else {
				deployInformationSlice, err := deploy.GetDeployInformationWithAutoUpdateForNewBuild(imageInformationUpgradeInput.ImageInformationName)
				if err != nil {
					log.Error(err)
				} else {
					for _, deployInformation := range deployInformationSlice {
						description := "Trigged by version " + imageInformation.CurrentVersion
						err := deploy.DeployUpdate(
							kubeApiServerEndPoint,
							kubeApiServerToken,
							deployInformation.Namespace,
							imageInformation.Name,
							imageInformation.CurrentVersion,
							description,
							deployInformation.EnvironmentSlice)
						if err != nil {
							log.Error(err)
						}
					}
				}
			}
		}
	}()
	/*
		outputMessage, err := image.BuildUpgrade(
			imageInformationUpgradeInput.ImageInformationName,
			imageInformationUpgradeInput.Description)

		resultJsonMap := make(map[string]interface{})
		resultJsonMap["OutputMessage"] = outputMessage
		statusCode := 200
		if err != nil {
			statusCode = 422
			resultJsonMap["Error"] = "Upgrade build failure"
			resultJsonMap["ErrorMessage"] = err.Error()
			resultJsonMap["imageInformationUpgradeInput"] = imageInformationUpgradeInput
			log.Error(resultJsonMap)
		}
		result, err := json.Marshal(resultJsonMap)
		if err != nil {
			jsonMap := make(map[string]interface{})
			jsonMap["Error"] = "Marshal output message failure"
			jsonMap["ErrorMessage"] = err.Error()
			jsonMap["resultJsonMap"] = resultJsonMap
			errorMessageByteSlice, _ := json.Marshal(jsonMap)
			log.Error(jsonMap)
			response.WriteErrorString(422, string(errorMessageByteSlice))
			return
		}

		response.WriteErrorString(statusCode, string(result))
		return
	*/
}
예제 #7
0
func DeployCreate(
	kubeApiServerEndPoint string, kubeApiServerToken string,
	namespace string, imageInformationName string,
	version string, description string, replicaAmount int,
	deployContainerPortSlice []DeployContainerPort,
	replicationControllerContainerEnvironmentSlice []control.ReplicationControllerContainerEnvironment,
	resourceMap map[string]interface{},
	extraJsonMap map[string]interface{},
	autoUpdateForNewBuild bool) error {
	if lock.AcquireLock(LockKind, getLockName(namespace, imageInformationName), 0) == false {
		return errors.New("Deployment is controlled by the other command")
	}

	defer lock.ReleaseLock(LockKind, getLockName(namespace, imageInformationName))

	imageRecord, err := image.GetStorage().LoadImageRecord(imageInformationName, version)
	if err != nil {
		log.Error("Load image record error: %s imageInformationName %s version %s", err, imageInformationName, version)
		return err
	}

	// Check whether the image in the private-registry
	privateRegistry, err := registry.GetPrivateRegistryFromPathAndTestAvailable(imageRecord.Path)
	if err != nil {
		log.Error("Get private registry access error: " + err.Error())
		return err
	}
	if privateRegistry.IsImageTagAvailable(imageRecord.ImageInformation, imageRecord.Version) == false {
		return errors.New("The image is not in the private-registry")
	}

	selectorName := imageInformationName
	replicationControllerName := selectorName + version
	image := imageRecord.Path

	// Automatically generate the basic default service. For advanced configuration, it should be modified in the service
	servicePortSlice := make([]control.ServicePort, 0)
	for _, deployContainerPort := range deployContainerPortSlice {
		containerPort := strconv.Itoa(deployContainerPort.ContainerPort)
		servicePort := control.ServicePort{
			deployContainerPort.Name,
			"TCP",
			deployContainerPort.ContainerPort,
			containerPort,
			deployContainerPort.NodePort, // -1 means not to use. 0 means auto-generated. > 0 means the port number to use
		}
		servicePortSlice = append(servicePortSlice, servicePort)
	}
	selectorLabelMap := make(map[string]interface{})
	selectorLabelMap["name"] = selectorName
	serviceLabelMap := make(map[string]interface{})
	serviceLabelMap["name"] = imageInformationName
	service := control.Service{
		imageInformationName,
		namespace,
		servicePortSlice,
		selectorLabelMap,
		"",
		serviceLabelMap,
		"",
	}
	err = control.CreateService(kubeApiServerEndPoint, kubeApiServerToken, namespace, service)
	if err != nil {
		log.Error("Create service error: %s", err)
		return err
	}

	// Replication controller
	replicationControllerContainerPortSlice := make([]control.ReplicationControllerContainerPort, 0)
	for _, deployContainerPort := range deployContainerPortSlice {
		replicationControllerContainerPortSlice = append(replicationControllerContainerPortSlice,
			control.ReplicationControllerContainerPort{deployContainerPort.Name, deployContainerPort.ContainerPort})
	}

	replicationControllerContainerSlice := make([]control.ReplicationControllerContainer, 0)
	replicationControllerContainerSlice = append(
		replicationControllerContainerSlice,
		control.ReplicationControllerContainer{
			replicationControllerName,
			image,
			replicationControllerContainerPortSlice,
			replicationControllerContainerEnvironmentSlice,
			resourceMap,
		})

	replicationController := control.ReplicationController{
		replicationControllerName,
		replicaAmount,
		control.ReplicationControllerSelector{
			selectorName,
			version,
		},
		control.ReplicationControllerLabel{
			replicationControllerName,
		},
		replicationControllerContainerSlice,
		extraJsonMap,
	}

	err = control.CreateReplicationController(kubeApiServerEndPoint, kubeApiServerToken,
		namespace, replicationController)
	if err != nil {
		log.Error("Create replication controller error: %s", err)
		return err
	}

	deployInformation := &DeployInformation{
		namespace,
		imageInformationName,
		version,
		imageRecord.Description,
		description,
		replicaAmount,
		deployContainerPortSlice,
		replicationControllerContainerEnvironmentSlice,
		resourceMap,
		extraJsonMap,
		time.Now(),
		autoUpdateForNewBuild,
	}

	err = GetStorage().saveDeployInformation(deployInformation)
	if err != nil {
		log.Error("Save deploy information error: %s", err)
		return err
	}

	return nil
}