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 */ }
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 }
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") }
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") }
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 }
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 */ }
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 }