403 lines
9.7 KiB
Go
403 lines
9.7 KiB
Go
package executor
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"net/url"
|
|
"strings"
|
|
|
|
schsdk "gitlink.org.cn/cloudream/common/sdks/scheduler"
|
|
"gitlink.org.cn/cloudream/common/utils/http2"
|
|
"gitlink.org.cn/cloudream/common/utils/serder"
|
|
)
|
|
|
|
type sugonHeader struct {
|
|
Token string `json:"token"`
|
|
}
|
|
|
|
func (c *HttpClient) CreateSugonInstance(token string, config map[string]interface{}) (string, error) {
|
|
targetURL, err := url.JoinPath(c.baseURL + "/ai/openapi/v2/instance-service/task")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
header := sugonHeader{
|
|
Token: token,
|
|
}
|
|
body, err := json.Marshal(config)
|
|
resp, err := http2.PostJSON(targetURL, http2.RequestParam{
|
|
Body: body,
|
|
Header: header,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading response body: %w", err)
|
|
}
|
|
contType := resp.Header.Get("Content-Type")
|
|
if strings.Contains(contType, http2.ContentTypeJSON) {
|
|
var codeResp response[any]
|
|
if err := serder.JSONToObject(bodyBytes, &codeResp); err != nil {
|
|
return "", fmt.Errorf("parsing response: %w", err)
|
|
}
|
|
|
|
if codeResp.Code == "0" {
|
|
return codeResp.Data.(string), nil
|
|
}
|
|
|
|
return "", codeResp.ToError()
|
|
}
|
|
|
|
return "", fmt.Errorf("unknow response content type: %s", contType)
|
|
}
|
|
|
|
type GetInstanceIDReq struct {
|
|
InstanceServiceName string `json:"instanceServiceName"`
|
|
TaskType string `json:"taskType"`
|
|
Start int `json:"start"`
|
|
Limit int `json:"limit"`
|
|
Status string `json:"status"`
|
|
Sort string `json:"sort"`
|
|
}
|
|
|
|
type instanceService struct {
|
|
ID string `json:"id"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
type GetInstanceIDResp struct {
|
|
Code string `json:"code"`
|
|
Msg string `json:"msg"`
|
|
Data []instanceService `json:"data"`
|
|
}
|
|
|
|
func (c *HttpClient) GetInstanceID(token string, instanceName string) (string, string, error) {
|
|
targetURL, err := url.JoinPath(c.baseURL + "/ai/openapi/v2/instance-service/task")
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
header := sugonHeader{
|
|
Token: token,
|
|
}
|
|
|
|
req := GetInstanceIDReq{
|
|
InstanceServiceName: instanceName,
|
|
//TaskType: "ssh",
|
|
Start: 0,
|
|
Limit: 20,
|
|
Sort: "desc",
|
|
}
|
|
|
|
resp, err := http2.GetJSON(targetURL, http2.RequestParam{
|
|
Body: req,
|
|
Header: header,
|
|
})
|
|
if err != nil {
|
|
return "", "", err
|
|
}
|
|
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", "", fmt.Errorf("reading response body: %w", err)
|
|
}
|
|
contType := resp.Header.Get("Content-Type")
|
|
if strings.Contains(contType, http2.ContentTypeJSON) {
|
|
var codeResp GetInstanceIDResp
|
|
if err := serder.JSONToObject(bodyBytes, &codeResp); err != nil {
|
|
return "", "", fmt.Errorf("parsing response: %w", err)
|
|
}
|
|
|
|
if codeResp.Code != "0" {
|
|
return "", "", err
|
|
}
|
|
|
|
if len(codeResp.Data) > 0 {
|
|
return codeResp.Data[0].ID, codeResp.Data[0].Status, nil
|
|
}
|
|
|
|
return "", "", err
|
|
}
|
|
|
|
return "", "", fmt.Errorf("unknow response content type: %s", contType)
|
|
}
|
|
|
|
type GetInstanceUrlResp struct {
|
|
ContainerPortInfoList []containerPortInfoList `json:"containerPortInfoList"`
|
|
}
|
|
|
|
type containerPortInfoList struct {
|
|
AccessUrl string `json:"accessUrl"`
|
|
}
|
|
|
|
func (c *HttpClient) GetInstanceUrl(token string, instanceID string) (string, error) {
|
|
path := "/ai/openapi/v2/instance-service/" + instanceID + "/detail"
|
|
targetURL, err := url.JoinPath(c.baseURL + path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
header := sugonHeader{
|
|
Token: token,
|
|
}
|
|
resp, err := http2.GetJSON(targetURL, http2.RequestParam{
|
|
Header: header,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading response body: %w", err)
|
|
}
|
|
contType := resp.Header.Get("Content-Type")
|
|
if strings.Contains(contType, http2.ContentTypeJSON) {
|
|
var codeResp response[GetInstanceUrlResp]
|
|
if err := serder.JSONToObject(bodyBytes, &codeResp); err != nil {
|
|
return "", fmt.Errorf("parsing response: %w", err)
|
|
}
|
|
|
|
if codeResp.Code != "0" {
|
|
return "", codeResp.ToError()
|
|
}
|
|
|
|
if len(codeResp.Data.ContainerPortInfoList) > 0 {
|
|
return codeResp.Data.ContainerPortInfoList[0].AccessUrl, nil
|
|
}
|
|
|
|
return "", codeResp.ToError()
|
|
}
|
|
|
|
return "", fmt.Errorf("unknow response content type: %s", contType)
|
|
}
|
|
|
|
func (c *HttpClient) OperateSugonInstance(token string, instanceID string, operate string) (string, error) {
|
|
var resp *http.Response
|
|
header := sugonHeader{
|
|
Token: token,
|
|
}
|
|
|
|
switch operate {
|
|
case schsdk.RunECS:
|
|
path := "/ai/openapi/v2/instance-service/task/actions/restart" + "?instanceServiceId=" + instanceID
|
|
targetURL, err := url.JoinPath(c.baseURL + path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
resp, err = http2.PostJSON(targetURL, http2.RequestParam{
|
|
Header: header,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
case schsdk.PauseECS:
|
|
path := "/ai/openapi/v2/instance-service/task/actions/stop" + "?ids=" + instanceID
|
|
targetURL, err := url.JoinPath(c.baseURL + path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
resp, err = http2.PostJSON(targetURL, http2.RequestParam{
|
|
Header: header,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
case schsdk.DestroyECS:
|
|
path := "/ai/openapi/v2/instance-service/task" + "?ids=" + instanceID
|
|
targetURL, err := url.JoinPath(c.baseURL + path)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
resp, err = http2.DeleteJSON(targetURL, http2.RequestParam{
|
|
Header: header,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
default:
|
|
return "", fmt.Errorf("unknow operate")
|
|
}
|
|
|
|
contType := resp.Header.Get("Content-Type")
|
|
if strings.Contains(contType, http2.ContentTypeJSON) {
|
|
var codeResp response[any]
|
|
if err := serder.JSONToObjectStream(resp.Body, &codeResp); err != nil {
|
|
return "", fmt.Errorf("parsing response: %w", err)
|
|
}
|
|
|
|
if codeResp.Code == "0" {
|
|
return codeResp.Code, nil
|
|
}
|
|
|
|
return "", codeResp.ToError()
|
|
}
|
|
|
|
return "", fmt.Errorf("unknow response content type: %s", contType)
|
|
}
|
|
|
|
type runCommandReq struct {
|
|
ID string `json:"id"`
|
|
StartScriptActionScope string `json:"startScriptActionScope"`
|
|
StartScriptContent string `json:"startScriptContent"`
|
|
}
|
|
|
|
func (c *HttpClient) RunCommand(token string, instanceID string, content string) (string, error) {
|
|
targetURL, err := url.JoinPath(c.baseURL + "/ai/openapi/v2/instance-service/task/actions/execute-script")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
header := sugonHeader{
|
|
Token: token,
|
|
}
|
|
req := runCommandReq{
|
|
ID: instanceID,
|
|
StartScriptActionScope: "header",
|
|
StartScriptContent: content,
|
|
}
|
|
resp, err := http2.PostJSON(targetURL, http2.RequestParam{
|
|
Header: header,
|
|
Body: req,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading response body: %w", err)
|
|
}
|
|
//logger.Info("run command result: " + string(bodyBytes))
|
|
|
|
contType := resp.Header.Get("Content-Type")
|
|
if strings.Contains(contType, http2.ContentTypeJSON) {
|
|
var codeResp response[any]
|
|
if err := serder.JSONToObject(bodyBytes, &codeResp); err != nil {
|
|
return "", fmt.Errorf("parsing response: %w", err)
|
|
}
|
|
|
|
if codeResp.Code == "0" {
|
|
return codeResp.Code, nil
|
|
}
|
|
|
|
return "", codeResp.ToError()
|
|
}
|
|
|
|
return "", fmt.Errorf("unknow response content type: %s", contType)
|
|
}
|
|
|
|
type previewFileReq struct {
|
|
Path string `json:"path"`
|
|
Force string `json:"force"`
|
|
StartIndex int `json:"startIndex"`
|
|
}
|
|
|
|
type previewFileResp struct {
|
|
Content string `json:"content"`
|
|
}
|
|
|
|
func (c *HttpClient) PreviewFile(token string, path string) (string, error) {
|
|
// 查询文件绝对路径
|
|
//fileUrl := c.baseURL + "/openapi/v2/file/list?limit=1000&start=0"
|
|
//filePath, err2 := c.getFileList(token, fileUrl, path)
|
|
//if err2 != nil {
|
|
// return "", err2
|
|
//}
|
|
|
|
targetURL, err := url.JoinPath(c.baseURL + "/openapi/v2/file/preview")
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
header := sugonHeader{
|
|
Token: token,
|
|
}
|
|
req := previewFileReq{
|
|
Path: path,
|
|
Force: "default",
|
|
StartIndex: 0,
|
|
}
|
|
resp, err := http2.PostForm(targetURL, http2.RequestParam{
|
|
Header: header,
|
|
Body: req,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading response body: %w", err)
|
|
}
|
|
|
|
contType := resp.Header.Get("Content-Type")
|
|
if strings.Contains(contType, http2.ContentTypeJSON) {
|
|
var codeResp response[previewFileResp]
|
|
if err := serder.JSONToObject(bodyBytes, &codeResp); err != nil {
|
|
return "", fmt.Errorf("parsing response: %w", err)
|
|
}
|
|
|
|
if codeResp.Code == "0" {
|
|
return codeResp.Data.Content, nil
|
|
}
|
|
|
|
return "", codeResp.ToError()
|
|
}
|
|
|
|
return "", fmt.Errorf("unknow response content type: %s", contType)
|
|
}
|
|
|
|
type fileListResp struct {
|
|
FileList []fileInfo `json:"fileList"`
|
|
}
|
|
|
|
type fileInfo struct {
|
|
Path string `json:"path"`
|
|
}
|
|
|
|
func (c *HttpClient) getFileList(token string, targetURL string, fileName string) (string, error) {
|
|
header := sugonHeader{
|
|
Token: token,
|
|
}
|
|
resp, err := http2.GetJSON(targetURL, http2.RequestParam{
|
|
Header: header,
|
|
})
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
bodyBytes, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return "", fmt.Errorf("reading response body: %w", err)
|
|
}
|
|
contType := resp.Header.Get("Content-Type")
|
|
if strings.Contains(contType, http2.ContentTypeJSON) {
|
|
var codeResp response[fileListResp]
|
|
if err := serder.JSONToObject(bodyBytes, &codeResp); err != nil {
|
|
return "", fmt.Errorf("parsing response: %w", err)
|
|
}
|
|
|
|
if codeResp.Code != "0" {
|
|
return "", codeResp.ToError()
|
|
}
|
|
|
|
if len(codeResp.Data.FileList) > 0 {
|
|
for _, file := range codeResp.Data.FileList {
|
|
if strings.Contains(file.Path, fileName) {
|
|
return file.Path, nil
|
|
}
|
|
}
|
|
return "", fmt.Errorf("file not found")
|
|
}
|
|
}
|
|
|
|
return "", fmt.Errorf("unknow response content type: %s", contType)
|
|
}
|