Skip to content

Commit

Permalink
feat: support offline package upload
Browse files Browse the repository at this point in the history
Signed-off-by: 张启航 <[email protected]>
  • Loading branch information
ZhangSetSail committed Jan 19, 2024
1 parent 4ac23ec commit 4399b39
Show file tree
Hide file tree
Showing 22 changed files with 1,035 additions and 110 deletions.
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
1 change: 1 addition & 0 deletions api/handler/helm.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ func (h *HelmAction) GetChartInformation(chart api_model.ChartInformation) (*[]a
return nil, &util.APIHandleError{Code: 400, Err: errors.Wrap(err, "GetChartInformation NewRequest")}
}
client := &http.Client{}
req.SetBasicAuth(chart.Username, chart.Password)
resp, err := client.Do(req)
if err != nil {
return nil, &util.APIHandleError{Code: 400, Err: errors.Wrap(err, "GetChartInformation client.Do")}
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
10 changes: 10 additions & 0 deletions api/model/model.go
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,8 @@ type CheckHelmApp struct {
type ChartInformation struct {
RepoURL string `json:"repo_url"`
ChartName string `json:"chart_name"`
Username string `json:"username"`
Password string `json:"password"`
}

// GetYamlByChart -
Expand Down Expand Up @@ -2242,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

0 comments on commit 4399b39

Please sign in to comment.