Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support custom build package upload #1847

Open
wants to merge 2 commits into
base: V5.17
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions api/api/api_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,10 @@ type ClusterInterface interface {
GetAbility(w http.ResponseWriter, r *http.Request)
UpdateAbility(w http.ResponseWriter, r *http.Request)
ListRainbondComponents(w http.ResponseWriter, r *http.Request)
GetLangVersion(w http.ResponseWriter, r *http.Request)
UpdateLangVersion(w http.ResponseWriter, r *http.Request)
CreateLangVersion(w http.ResponseWriter, r *http.Request)
DeleteLangVersion(w http.ResponseWriter, r *http.Request)
}

// NodesInterface -
Expand Down Expand Up @@ -211,6 +215,13 @@ type AppInterface interface {
UploadID(w http.ResponseWriter, r *http.Request)
}

// LongVersionInterface long version interface
type LongVersionInterface interface {
UploadLongVersion(w http.ResponseWriter, r *http.Request)
OptionLongVersion(w http.ResponseWriter, r *http.Request)
DownloadLongVersion(w http.ResponseWriter, r *http.Request)
}

// ApplicationInterface tenant application interface
type ApplicationInterface interface {
CreateApp(w http.ResponseWriter, r *http.Request)
Expand Down
4 changes: 4 additions & 0 deletions api/api_routers/version2/v2Routers.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ func (v2 *V2) clusterRouter() chi.Router {
r.Get("/governance-mode", controller.GetManager().ListGovernanceMode)
r.Get("/rbd-components", controller.GetManager().ListRainbondComponents)
r.Mount("/nodes", v2.nodesRouter())
r.Get("/langVersion", controller.GetManager().GetLangVersion)
r.Post("/langVersion", controller.GetManager().CreateLangVersion)
r.Put("/langVersion", controller.GetManager().UpdateLangVersion)
r.Delete("/langVersion", controller.GetManager().DeleteLangVersion)
return r
}

Expand Down
14 changes: 12 additions & 2 deletions api/api_routers/websocket/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,8 @@
package websocket

import (
"github.com/goodrain/rainbond/api/controller"

"github.com/go-chi/chi"
"github.com/goodrain/rainbond/api/controller"
)

// Routes routes
Expand Down Expand Up @@ -60,3 +59,14 @@ func PackageBuildRoutes() chi.Router {
r.Options("/component/events/{eventID}", controller.GetManager().UploadPackage)
return r
}

// LongVersionRoutes 语言包处理
func LongVersionRoutes() chi.Router {
r := chi.NewRouter()
r.Options("/upload", controller.GetManager().OptionLongVersion)
r.Post("/upload", controller.GetManager().UploadLongVersion)
//r.Options("/download/{language}/{version}", controller.GetManager().OptionLongVersion)
r.Get("/download/{language}/{version}", controller.GetManager().DownloadLongVersion)
r.Head("/download/{language}/{version}", controller.GetManager().DownloadLongVersion)
return r
}
63 changes: 63 additions & 0 deletions api/controller/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import (
dbmodel "github.com/goodrain/rainbond/db/model"
"github.com/sirupsen/logrus"
"net/http"
"os"
"path"
"strconv"

httputil "github.com/goodrain/rainbond/util/http"
Expand Down Expand Up @@ -462,3 +464,64 @@ func (c *ClusterController) UpdateAbility(w http.ResponseWriter, r *http.Request
}
httputil.ReturnSuccess(r, w, nil)
}

// GetLangVersion Get the unconnected namespaces under the current cluster
func (c *ClusterController) GetLangVersion(w http.ResponseWriter, r *http.Request) {
language := r.URL.Query().Get("language")
versions, err := db.GetManager().LongVersionDao().ListVersionByLanguage(language)
if err != nil {
httputil.ReturnBcodeError(r, w, fmt.Errorf("update lang version failure: %v", err))
return
}
httputil.ReturnSuccess(r, w, versions)
}

// UpdateLangVersion -
func (c *ClusterController) UpdateLangVersion(w http.ResponseWriter, r *http.Request) {
var lang model.UpdateLangVersion
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &lang, nil); !ok {
httputil.ReturnError(r, w, 400, "failed to parse parameters")
return
}
err := db.GetManager().LongVersionDao().DefaultLangVersion(lang.Lang, lang.Version)
if err != nil {
httputil.ReturnError(r, w, 400, fmt.Sprintf("update lang version failure: %v", err))
return
}
httputil.ReturnSuccess(r, w, "更新成功")
}

// CreateLangVersion -
func (c *ClusterController) CreateLangVersion(w http.ResponseWriter, r *http.Request) {
var lang model.UpdateLangVersion
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &lang, nil); !ok {
httputil.ReturnError(r, w, 400, "failed to parse parameters")
return
}
err := db.GetManager().LongVersionDao().CreateLangVersion(lang.Lang, lang.Version, lang.EventID, lang.FileName)
if err != nil {
httputil.ReturnError(r, w, 400, fmt.Sprintf("create lang version failure: %v", err))
return
}
httputil.ReturnSuccess(r, w, "创建成功")
}

// DeleteLangVersion -
func (c *ClusterController) DeleteLangVersion(w http.ResponseWriter, r *http.Request) {
var lang model.UpdateLangVersion
if ok := httputil.ValidatorRequestStructAndErrorResponse(r, w, &lang, nil); !ok {
httputil.ReturnError(r, w, 400, "failed to parse parameters")
return
}
eventID, err := db.GetManager().LongVersionDao().DeleteLangVersion(lang.Lang, lang.Version)
if err != nil {
httputil.ReturnError(r, w, 400, fmt.Sprintf("delete lang version failure: %v", err))
return
}
err = os.RemoveAll(path.Join(BaseUploadPath, eventID))
if err != nil {
httputil.ReturnError(r, w, 400, fmt.Sprintf("delete lang version pack failure: %v", err))
return
}
httputil.ReturnSuccess(r, w, "删除成功")
}
134 changes: 134 additions & 0 deletions api/controller/lg_pack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
package controller

import (
"encoding/json"
"github.com/go-chi/chi"
"github.com/goodrain/rainbond/db"
httputil "github.com/goodrain/rainbond/util/http"
"io"
"math/rand"
"net/http"
"os"
"path"
"reflect"
"strings"
)

// LongVersionStruct -
type LongVersionStruct struct{}

// BaseUploadPath lang version base dir
const BaseUploadPath = "/grdata/lang"

// UploadLongVersion -
func (t *LongVersionStruct) UploadLongVersion(w http.ResponseWriter, r *http.Request) {
//从表单中读取文件
file, fileHeader, err := r.FormFile("file")
if err != nil {
sendResponse(w, http.StatusBadRequest, "failure", "get file failure.")
return
}
//defer 结束时关闭文件
defer file.Close()
eventID, err := generateRandomString(32)
langPath := path.Join(BaseUploadPath, eventID)
_, err = os.Stat(langPath)
if os.IsNotExist(err) {
// 创建文件夹
err := os.MkdirAll(langPath, os.ModePerm)
if err != nil {
sendResponse(w, http.StatusInternalServerError, "failure", "dir is not exist,mkdir failure")
return
}
}
//创建文件
newFile, err := os.Create(path.Join(langPath, fileHeader.Filename))
if err != nil {
sendResponse(w, http.StatusInternalServerError, "failure", "Create file error"+err.Error())
return
}
//defer 结束时关闭文件
defer newFile.Close()

//将文件写到本地
_, err = io.Copy(newFile, file)
if err != nil {
sendResponse(w, http.StatusInternalServerError, "failure", "Failed to write file: "+err.Error())
return
}
long := struct {
EventID string `json:"event_id"`
FileName string `json:"file_name"`
}{
eventID,
fileHeader.Filename,
}
origin := r.Header.Get("Origin")
w.Header().Add("Access-Control-Allow-Origin", origin)
w.Header().Add("Access-Control-Allow-Methods", "POST, GET, DELETE, PUT, OPTIONS")
w.Header().Add("Access-Control-Allow-Credentials", "true")
w.Header().Add("Access-Control-Allow-Headers", "authorization,x_region_name,x_team_name,x-requested-with")
sendResponse(w, http.StatusOK, "successful", long)
}

// DownloadLongVersion -
func (t *LongVersionStruct) DownloadLongVersion(w http.ResponseWriter, r *http.Request) {
language := strings.TrimSpace(chi.URLParam(r, "language"))
version := strings.TrimSpace(chi.URLParam(r, "version"))
ver, err := db.GetManager().LongVersionDao().GetVersionByLanguageAndVersion(language, version)
if err != nil {
sendResponse(w, http.StatusBadRequest, "failure", "get version failure"+err.Error())
return
}
http.ServeFile(w, r, path.Join(BaseUploadPath, ver.EventID, ver.FileName))
}

// OptionLongVersion -
func (t *LongVersionStruct) OptionLongVersion(w http.ResponseWriter, r *http.Request) {
origin := r.Header.Get("Origin")
w.Header().Add("Access-Control-Allow-Origin", origin)
w.Header().Add("Access-Control-Allow-Methods", "POST, GET, DELETE, PUT, OPTIONS")
w.Header().Add("Access-Control-Allow-Credentials", "true")
w.Header().Add("Access-Control-Allow-Headers", "authorization,x_region_name,x_team_name,content-type,x-requested-with")
httputil.ReturnSuccess(r, w, nil)
return
}

func generateRandomString(n int) (string, error) {
const letters = "abcdefghijklmnopqrstuvwxyz0123456789"
bytes := make([]byte, n)
if _, err := rand.Read(bytes); err != nil {
return "", err
}
for i, b := range bytes {
bytes[i] = letters[b%byte(len(letters))]
}
return string(bytes), nil
}

// APIResponse =
type APIResponse struct {
Code int `json:"code"`
Message string `json:"message"`
Bean interface{} `json:"bean,omitempty"`
List interface{} `json:"list,omitempty"`
}

func sendResponse(w http.ResponseWriter, code int, message string, data interface{}) {
w.Header().Set("Content-Type", "application/json")
w.WriteHeader(code)

response := APIResponse{
Code: code,
Message: message,
}

switch reflect.TypeOf(data).Kind() {
case reflect.Slice, reflect.Array:
response.List = data
default:
response.Bean = data
}

json.NewEncoder(w).Encode(response)
}
1 change: 1 addition & 0 deletions api/controller/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ type V2Manager interface {
api.PluginInterface
api.RulesInterface
api.AppInterface
api.LongVersionInterface
api.Gatewayer
api.ThirdPartyServicer
api.Labeler
Expand Down
1 change: 1 addition & 0 deletions api/controller/resources.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ type V2Routes struct {
TenantStruct
EventLogStruct
AppStruct
LongVersionStruct
GatewayStruct
ThirdPartyServiceController
LabelController
Expand Down
2 changes: 1 addition & 1 deletion api/handler/resource_import.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"time"
)

//ResourceImport Import the converted k8s resources into recognition
// ResourceImport Import the converted k8s resources into recognition
func (c *clusterAction) ResourceImport(namespace string, as map[string]model.ApplicationResource, eid string) (*model.ReturnResourceImport, *util.APIHandleError) {
logrus.Infof("ResourceImport function begin")
var returnResourceImport model.ReturnResourceImport
Expand Down
8 changes: 8 additions & 0 deletions api/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -2244,3 +2244,11 @@ type UploadChartValueYaml struct {
Values map[string]string `json:"values"`
Readme string `json:"readme"`
}

// UpdateLangVersion -
type UpdateLangVersion struct {
Lang string `json:"lang"`
Version string `json:"version"`
EventID string `json:"event_id"`
FileName string `json:"file_name"`
}
1 change: 1 addition & 0 deletions api/server/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ func (m *Manager) Run() {
websocketRouter.Mount("/logs", websocket.LogRoutes())
websocketRouter.Mount("/app", websocket.AppRoutes())
websocketRouter.Mount("/package_build", websocket.PackageBuildRoutes())
websocketRouter.Mount("/lg_pack_operate", websocket.LongVersionRoutes())
if m.conf.WebsocketSSL {
logrus.Infof("websocket listen on (HTTPs) %s", m.conf.WebsocketAddr)
logrus.Fatal(http.ListenAndServeTLS(m.conf.WebsocketAddr, m.conf.WebsocketCertFile, m.conf.WebsocketKeyFile, websocketRouter))
Expand Down
48 changes: 48 additions & 0 deletions builder/build/code_build.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/goodrain/rainbond/db"
"io"
"io/ioutil"
"os"
Expand Down Expand Up @@ -358,6 +359,53 @@ func (s *slugBuild) runBuildJob(re *Request) error {
v = "web: " + v[4:]
}
}
if k == "RUNTIMES" || k == "GOVERSION" {
var lang string
switch re.Lang {
case code.Python:
lang = "python"
case code.Golang:
lang = "golang"
case code.JavaJar, code.JavaMaven, code.JaveWar, code.Gradle:
lang = "openJDK"
case code.PHP:
lang = "php"
case code.Nodejs, code.NodeJSStatic:
lang = "node"
}
version, err := db.GetManager().LongVersionDao().GetVersionByLanguageAndVersion(lang, v)
if err != nil {
return err
}
if !version.System {
envs = append(envs, corev1.EnvVar{Name: "CUSTOMIZE_RUNTIMES", Value: "true"})
envs = append(envs, corev1.EnvVar{Name: "CUSTOMIZE_RUNTIMES_URL", Value: fmt.Sprintf("rbd-api-websocket:6060/lg_pack_operate/download/%v/%v", lang, v)})
}
}
if k == "RUNTIMES_MAVEN" {
version, err := db.GetManager().LongVersionDao().GetVersionByLanguageAndVersion("maven", v)
if err != nil {
return err
}
if !version.System {
envs = append(envs, corev1.EnvVar{Name: "CUSTOMIZE_RUNTIMES_MAVEN", Value: "true"})
envs = append(envs, corev1.EnvVar{Name: "CUSTOMIZE_RUNTIMES_MAVEN_URL", Value: fmt.Sprintf("rbd-api-websocket:6060/lg_pack_operate/download/maven/%v", v)})
}
}
if k == "RUNTIMES_SERVER" {
language := "web_compiler"
if re.Lang == code.Static || re.Lang == code.PHP {
language = "web_runtime"
}
version, err := db.GetManager().LongVersionDao().GetVersionByLanguageAndVersion(language, v)
if err != nil {
return err
}
if !version.System {
envs = append(envs, corev1.EnvVar{Name: "CUSTOMIZE_RUNTIMES_SERVER", Value: "true"})
envs = append(envs, corev1.EnvVar{Name: "CUSTOMIZE_RUNTIMES_SERVER_URL", Value: fmt.Sprintf("rbd-api-websocket:6060/lg_pack_operate/download/%v/%v", language, v)})
}
}
envs = append(envs, corev1.EnvVar{Name: k, Value: v})
if k == "PROC_ENV" {
var mapdata = make(map[string]interface{})
Expand Down
Loading
Loading