mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
add host iso&pxe register
This commit is contained in:
@@ -23,14 +23,13 @@ import (
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
"yunion.io/x/onecloud/pkg/apigateway/options"
|
||||
|
||||
"github.com/360EntSecGroup-Skylar/excelize"
|
||||
"golang.org/x/sync/errgroup"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apigateway/options"
|
||||
"yunion.io/x/onecloud/pkg/appctx"
|
||||
"yunion.io/x/onecloud/pkg/appsrv"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
@@ -39,6 +38,19 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
const (
|
||||
HOST_MAC = "*MAC地址"
|
||||
HOST_NAME = "*名称"
|
||||
HOST_IPMI_ADDR = "*IPMI地址"
|
||||
HOST_IPMI_USERNAME = "*IPMI用户名"
|
||||
HOST_IPMI_PASSWORD = "*IPMI密码"
|
||||
HOST_MNG_IP_ADDR = "*管理口IP地址"
|
||||
HOST_IPMI_ADDR_OPTIONAL = "IPMI地址"
|
||||
HOST_IPMI_USERNAME_OPTIONAL = "IPMI用户名"
|
||||
HOST_IPMI_PASSWORD_OPTIONAL = "IPMI密码"
|
||||
HOST_MNG_IP_ADDR_OPTIONAL = "管理口IP地址"
|
||||
)
|
||||
|
||||
func FetchSession(ctx context.Context, r *http.Request, apiVersion string) *mcclient.ClientSession {
|
||||
token := AppContextToken(ctx)
|
||||
session := auth.GetSession(ctx, token, FetchRegion(r), apiVersion)
|
||||
@@ -142,22 +154,48 @@ func (mh *MiscHandler) DoBatchHostRegister(ctx context.Context, w http.ResponseW
|
||||
log.Errorf(err.Error())
|
||||
e := httperrors.NewInternalServerError("can't parse file")
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
}
|
||||
|
||||
rows := xlsx.GetRows("hosts")
|
||||
if len(rows) == 0 {
|
||||
e := httperrors.NewGeneralError(fmt.Errorf("empty file content"))
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
}
|
||||
|
||||
h := ""
|
||||
paramKeys := []string{}
|
||||
for _, title := range rows[0] {
|
||||
switch title {
|
||||
case HOST_MAC:
|
||||
paramKeys = append(paramKeys, "access_mac")
|
||||
case HOST_NAME:
|
||||
paramKeys = append(paramKeys, "name")
|
||||
case HOST_IPMI_ADDR, HOST_IPMI_ADDR_OPTIONAL:
|
||||
paramKeys = append(paramKeys, "ipmi_ip_addr")
|
||||
case HOST_IPMI_USERNAME, HOST_IPMI_USERNAME_OPTIONAL:
|
||||
paramKeys = append(paramKeys, "ipmi_username")
|
||||
case HOST_IPMI_PASSWORD, HOST_IPMI_PASSWORD_OPTIONAL:
|
||||
paramKeys = append(paramKeys, "ipmi_password")
|
||||
case HOST_MNG_IP_ADDR, HOST_MNG_IP_ADDR_OPTIONAL:
|
||||
paramKeys = append(paramKeys, "access_ip")
|
||||
default:
|
||||
e := httperrors.NewInternalServerError("empty file content")
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// skipped header row
|
||||
for _, row := range xlsx.GetRows("hosts")[1:] {
|
||||
if len(row) < 4 {
|
||||
log.Debugf("batchHostRegister row length too short (less than 4) %s", row)
|
||||
}
|
||||
|
||||
h = h + strings.Join(row, ",") + "\n"
|
||||
}
|
||||
|
||||
s := FetchSession(ctx, req, "")
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("hosts", jsonutils.NewString(h))
|
||||
resp, err := modules.Hosts.DoBatchRegister(s, params)
|
||||
resp, err := modules.Hosts.DoBatchRegister(s, paramKeys, params)
|
||||
if err != nil {
|
||||
e := httperrors.NewGeneralError(err)
|
||||
httperrors.JsonClientError(w, e)
|
||||
@@ -200,21 +238,38 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
log.Errorf(err.Error())
|
||||
e := httperrors.NewInternalServerError("can't parse file")
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
}
|
||||
|
||||
// skipped header row
|
||||
names := map[string]string{}
|
||||
rows := xlsx.GetRows("users")
|
||||
if len(rows) <= 1 {
|
||||
e := httperrors.NewInputParameterError("empty file")
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
}
|
||||
|
||||
users := []jsonutils.JSONObject{}
|
||||
names := map[string]bool{}
|
||||
domains := map[string]string{}
|
||||
users := []jsonutils.JSONDict{}
|
||||
for _, row := range xlsx.GetRows("users")[1:] {
|
||||
if len(row) < 3 {
|
||||
log.Debugf("batchHostRegister row length too short (less than 3) %s", row)
|
||||
for i, row := range rows[1:] {
|
||||
name := row[0]
|
||||
if len(name) == 0 {
|
||||
e := httperrors.NewClientError("row %d name is empty", i+2)
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
}
|
||||
|
||||
if _, ok := names[row[0]]; ok {
|
||||
if _, ok := names[name]; ok {
|
||||
e := httperrors.NewClientError("duplicate name %s", row[0])
|
||||
httperrors.JsonClientError(w, e)
|
||||
return
|
||||
} else {
|
||||
names[name] = true
|
||||
_, err := modules.UsersV3.Get(s, name, nil)
|
||||
if err == nil {
|
||||
continue
|
||||
}
|
||||
}
|
||||
|
||||
domainId, ok := domains[row[1]]
|
||||
@@ -230,14 +285,16 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
}
|
||||
|
||||
user := jsonutils.NewDict()
|
||||
user.Add(jsonutils.NewString(row[0]), "name")
|
||||
user.Add(jsonutils.NewString(name), "name")
|
||||
user.Add(jsonutils.NewString(domainId), "domain_id")
|
||||
user.Add(jsonutils.NewString("OneCloud@2019"), "password")
|
||||
if strings.ToLower(row[2]) == "true" {
|
||||
if strings.ToLower(row[2]) == "true" || strings.ToLower(row[2]) == "1" {
|
||||
user.Add(jsonutils.JSONTrue, "allow_web_console")
|
||||
} else {
|
||||
user.Add(jsonutils.JSONFalse, "allow_web_console")
|
||||
}
|
||||
|
||||
users = append(users, user)
|
||||
}
|
||||
|
||||
// batch create
|
||||
@@ -245,7 +302,7 @@ func (mh *MiscHandler) DoBatchUserRegister(ctx context.Context, w http.ResponseW
|
||||
for i := range users {
|
||||
user := users[i]
|
||||
userG.Go(func() error {
|
||||
_, err := modules.Users.Create(s, &user)
|
||||
_, err := modules.UsersV3.Create(s, user)
|
||||
return err
|
||||
})
|
||||
}
|
||||
@@ -271,7 +328,21 @@ func (mh *MiscHandler) getDownloadsHandler(ctx context.Context, w http.ResponseW
|
||||
var content bytes.Buffer
|
||||
switch template {
|
||||
case "BatchHostRegister":
|
||||
records := [][]string{{"MAC地址", "名称", "IPMI地址", "IPMI用户名", "IPMI密码"}}
|
||||
records := [][]string{{HOST_MAC, HOST_NAME, HOST_IPMI_ADDR_OPTIONAL, HOST_IPMI_USERNAME_OPTIONAL, HOST_IPMI_PASSWORD_OPTIONAL}}
|
||||
content, err = writeXlsx("hosts", records)
|
||||
if err != nil {
|
||||
httperrors.InternalServerError(w, "internal server error")
|
||||
return
|
||||
}
|
||||
case "BatchHostISORegister":
|
||||
records := [][]string{{HOST_NAME, HOST_IPMI_ADDR, HOST_IPMI_USERNAME, HOST_IPMI_PASSWORD, HOST_MNG_IP_ADDR}}
|
||||
content, err = writeXlsx("hosts", records)
|
||||
if err != nil {
|
||||
httperrors.InternalServerError(w, "internal server error")
|
||||
return
|
||||
}
|
||||
case "BatchHostPXERegister":
|
||||
records := [][]string{{HOST_NAME, HOST_IPMI_ADDR, HOST_IPMI_USERNAME, HOST_IPMI_PASSWORD, HOST_MNG_IP_ADDR_OPTIONAL}}
|
||||
content, err = writeXlsx("hosts", records)
|
||||
if err != nil {
|
||||
httperrors.InternalServerError(w, "internal server error")
|
||||
@@ -304,7 +375,7 @@ func (mh *MiscHandler) getDownloadsHandler(ctx context.Context, w http.ResponseW
|
||||
}
|
||||
|
||||
w.Header().Set("Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet")
|
||||
w.Header().Set("Content-Disposition", "Attachment; filename=hosts_template.xlsx")
|
||||
w.Header().Set("Content-Disposition", "Attachment; filename=template.xlsx")
|
||||
w.Write(content.Bytes())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -16,7 +16,6 @@ package modules
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
@@ -89,7 +88,7 @@ func (this *HostManager) GetIpmiInfo(s *mcclient.ClientSession, id string, param
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func parseHosts(data string) ([]jsonutils.JSONObject, string) {
|
||||
func parseHosts(titles []string, data string) ([]jsonutils.JSONObject, string) {
|
||||
msg := ""
|
||||
hosts := strings.Split(data, "\n")
|
||||
ret := []jsonutils.JSONObject{}
|
||||
@@ -101,37 +100,15 @@ func parseHosts(data string) ([]jsonutils.JSONObject, string) {
|
||||
}
|
||||
|
||||
fields := strings.Split(host, ",")
|
||||
if len(fields) != 5 {
|
||||
msg += fmt.Sprintf("第%d行: %s (格式不正确)\n", i, host)
|
||||
continue
|
||||
}
|
||||
|
||||
// mac address check
|
||||
if match, err := regexp.MatchString(MACAddressPattern, fields[0]); err != nil || !match {
|
||||
msg += fmt.Sprintf("第%d行: %s (Mac地址格式不正确)\n", i, host)
|
||||
continue
|
||||
}
|
||||
|
||||
// name check
|
||||
if len(fields[1]) == 0 {
|
||||
msg += fmt.Sprintf("第%d行: %s (名称不能为空)\n", i, host)
|
||||
}
|
||||
|
||||
params := jsonutils.NewDict()
|
||||
params.Add(jsonutils.NewString(fields[0]), "access_mac")
|
||||
params.Add(jsonutils.NewString(fields[1]), "name")
|
||||
params.Add(jsonutils.NewString("baremetal"), "host_type")
|
||||
|
||||
if len(fields[2]) > 0 {
|
||||
params.Add(jsonutils.NewString(fields[2]), "ipmi_ip_addr")
|
||||
}
|
||||
|
||||
if len(fields[3]) > 0 {
|
||||
params.Add(jsonutils.NewString(fields[3]), "ipmi_username")
|
||||
}
|
||||
|
||||
if len(fields[4]) > 0 {
|
||||
params.Add(jsonutils.NewString(fields[4]), "ipmi_password")
|
||||
for i := range fields {
|
||||
field := fields[i]
|
||||
if len(field) > 0 {
|
||||
params.Add(jsonutils.NewString(field), titles[i])
|
||||
}
|
||||
}
|
||||
|
||||
ret = append(ret, params)
|
||||
@@ -140,13 +117,13 @@ func parseHosts(data string) ([]jsonutils.JSONObject, string) {
|
||||
return ret, msg
|
||||
}
|
||||
|
||||
func (this *HostManager) DoBatchRegister(s *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
func (this *HostManager) DoBatchRegister(s *mcclient.ClientSession, titles []string, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
data, err := params.GetString("hosts")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
hosts, msg := parseHosts(data)
|
||||
hosts, msg := parseHosts(titles, data)
|
||||
if len(msg) > 0 {
|
||||
return nil, httperrors.NewInputParameterError(msg)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user