mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-06 21:52:54 +08:00
fix: compatiblity fixes with lenovo RD620 and huawei 2288
This commit is contained in:
167
cmd/raidcli/main.go
Normal file
167
cmd/raidcli/main.go
Normal file
@@ -0,0 +1,167 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"yunion.io/x/structarg"
|
||||
|
||||
_ "yunion.io/x/onecloud/cmd/raidcli/shell"
|
||||
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
|
||||
"yunion.io/x/onecloud/pkg/baremetal/utils/raid/drivers"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
"yunion.io/x/onecloud/pkg/util/ssh"
|
||||
)
|
||||
|
||||
type BaseOptions struct {
|
||||
Debug bool `help:"debug mode"`
|
||||
Help bool `help:"Show help"`
|
||||
Host string `help:"SSH Host IP" default:"$RAID_HOST" metavar:"RAID_HOST"`
|
||||
Username string `help:"Username, usually root" default:"$RAID_USERNAME" metavar:"RAID_USERNAME"`
|
||||
Password string `help:"Password" default:"$RAID_PASSWORD" metavar:"RAID_PASSWORD"`
|
||||
Driver string `help:"Password" default:"$RAID_DRIVER" metavar:"RAID_DRIVER" choices:"MegaRaid|HPSARaid|Mpt2SAS|MarvelRaid"`
|
||||
SUBCOMMAND string `help:"s3cli subcommand" subcommand:"true"`
|
||||
}
|
||||
|
||||
var (
|
||||
options = &BaseOptions{}
|
||||
)
|
||||
|
||||
func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
parse, e := structarg.NewArgumentParser(options,
|
||||
"raidcli",
|
||||
"Command-line interface to test RAID drivers.",
|
||||
`See "raidcli help COMMAND" for help on a specific command.`)
|
||||
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
|
||||
subcmd := parse.GetSubcommand()
|
||||
if subcmd == nil {
|
||||
return nil, fmt.Errorf("No subcommand argument.")
|
||||
}
|
||||
type HelpOptions struct {
|
||||
SUBCOMMAND string `help:"sub-command name"`
|
||||
}
|
||||
shellutils.R(&HelpOptions{}, "help", "Show help of a subcommand", func(args *HelpOptions) error {
|
||||
helpstr, e := subcmd.SubHelpString(args.SUBCOMMAND)
|
||||
if e != nil {
|
||||
return e
|
||||
} else {
|
||||
fmt.Print(helpstr)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
for _, v := range shellutils.CommandTable {
|
||||
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
|
||||
if e != nil {
|
||||
return nil, e
|
||||
}
|
||||
}
|
||||
return parse, nil
|
||||
}
|
||||
|
||||
func showErrorAndExit(e error) {
|
||||
fmt.Fprintf(os.Stderr, "%s", e)
|
||||
fmt.Fprintln(os.Stderr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newClient() (raid.IRaidDriver, error) {
|
||||
if len(options.Host) == 0 {
|
||||
return nil, fmt.Errorf("Missing host")
|
||||
}
|
||||
|
||||
if len(options.Username) == 0 {
|
||||
return nil, fmt.Errorf("Missing username")
|
||||
}
|
||||
|
||||
if len(options.Password) == 0 {
|
||||
return nil, fmt.Errorf("Missing password")
|
||||
}
|
||||
|
||||
if len(options.Driver) == 0 {
|
||||
return nil, fmt.Errorf("Missing driver")
|
||||
}
|
||||
|
||||
if options.Debug {
|
||||
raid.Debug = true
|
||||
}
|
||||
|
||||
sshClient, err := ssh.NewClient(
|
||||
options.Host,
|
||||
22,
|
||||
options.Username,
|
||||
options.Password,
|
||||
"",
|
||||
)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("ssh client init fail: %s", err)
|
||||
}
|
||||
|
||||
drv := drivers.GetDriver(options.Driver, sshClient)
|
||||
if drv == nil {
|
||||
return nil, fmt.Errorf("not supported driver %s", options.Driver)
|
||||
}
|
||||
|
||||
err = drv.ParsePhyDevs()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("parse phyical devices error %s", err)
|
||||
}
|
||||
|
||||
return drv, nil
|
||||
}
|
||||
|
||||
func main() {
|
||||
parser, e := getSubcommandParser()
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = parser.ParseArgs(os.Args[1:], false)
|
||||
// options := parser.Options().(*BaseOptions)
|
||||
|
||||
if options.Help {
|
||||
fmt.Print(parser.HelpString())
|
||||
} else {
|
||||
subcmd := parser.GetSubcommand()
|
||||
subparser := subcmd.GetSubParser()
|
||||
if e != nil {
|
||||
if subparser != nil {
|
||||
fmt.Print(subparser.Usage())
|
||||
} else {
|
||||
fmt.Print(parser.Usage())
|
||||
}
|
||||
showErrorAndExit(e)
|
||||
} else {
|
||||
suboptions := subparser.Options()
|
||||
if options.SUBCOMMAND == "help" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
var client raid.IRaidDriver
|
||||
client, e = newClient()
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = subcmd.Invoke(client, suboptions)
|
||||
}
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
37
cmd/raidcli/shell/raid.go
Normal file
37
cmd/raidcli/shell/raid.go
Normal file
@@ -0,0 +1,37 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package shell
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"yunion.io/x/jsonutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/baremetal/utils/raid"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
|
||||
func init() {
|
||||
type ShowOptions struct {
|
||||
}
|
||||
shellutils.R(&ShowOptions{}, "show", "show raid info", func(drv raid.IRaidDriver, args *ShowOptions) error {
|
||||
adpts := drv.GetAdapters()
|
||||
for i := range adpts {
|
||||
fmt.Println("Index:", i)
|
||||
fmt.Println(jsonutils.Marshal(adpts[i].GetDevices()).PrettyString())
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}
|
||||
@@ -17,12 +17,16 @@ package main
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"yunion.io/x/structarg"
|
||||
|
||||
_ "yunion.io/x/onecloud/cmd/redfishcli/shell"
|
||||
"yunion.io/x/onecloud/pkg/util/fileutils2"
|
||||
"yunion.io/x/onecloud/pkg/util/redfish"
|
||||
"yunion.io/x/onecloud/pkg/util/redfish/bmconsole"
|
||||
_ "yunion.io/x/onecloud/pkg/util/redfish/loader"
|
||||
"yunion.io/x/onecloud/pkg/util/shellutils"
|
||||
)
|
||||
@@ -36,8 +40,12 @@ type BaseOptions struct {
|
||||
SUBCOMMAND string `help:"s3cli subcommand" subcommand:"true"`
|
||||
}
|
||||
|
||||
var (
|
||||
options = &BaseOptions{}
|
||||
)
|
||||
|
||||
func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
parse, e := structarg.NewArgumentParser(&BaseOptions{},
|
||||
parse, e := structarg.NewArgumentParser(options,
|
||||
"redfishcli",
|
||||
"Command-line interface to redfish API.",
|
||||
`See "redfishcli help COMMAND" for help on a specific command.`)
|
||||
@@ -62,6 +70,7 @@ func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
return nil
|
||||
}
|
||||
})
|
||||
bmcJnlp()
|
||||
for _, v := range shellutils.CommandTable {
|
||||
_, e := subcmd.AddSubParser(v.Options, v.Command, v.Desc, v.Callback)
|
||||
if e != nil {
|
||||
@@ -71,13 +80,49 @@ func getSubcommandParser() (*structarg.ArgumentParser, error) {
|
||||
return parse, nil
|
||||
}
|
||||
|
||||
func bmcJnlp() {
|
||||
type BmcGetOptions struct {
|
||||
BRAND string `help:"brand of baremetal" choices:"Lenovo|Huawei|HPE|Dell|Supermicro"`
|
||||
Save string `help:"save to file"`
|
||||
Debug bool `help:"turn on debug mode"`
|
||||
}
|
||||
shellutils.R(&BmcGetOptions{}, "bmc-jnlp", "Get Java Console JNLP file", func(args *BmcGetOptions) error {
|
||||
ctx := context.Background()
|
||||
parts, err := url.Parse(options.Endpoint)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bmc := bmconsole.NewBMCConsole(parts.Hostname(), options.Username, options.Password, args.Debug)
|
||||
var jnlp string
|
||||
switch strings.ToLower(args.BRAND) {
|
||||
case "hp", "hpe":
|
||||
jnlp, err = bmc.GetIloConsoleJNLP(ctx)
|
||||
case "dell", "dell inc.":
|
||||
jnlp, err = bmc.GetIdracConsoleJNLP(ctx, "", "")
|
||||
case "supermicro":
|
||||
jnlp, err = bmc.GetSupermicroConsoleJNLP(ctx)
|
||||
case "lenovo":
|
||||
jnlp, err = bmc.GetLenovoConsoleJNLP(ctx)
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(args.Save) > 0 {
|
||||
return fileutils2.FilePutContents(args.Save, jnlp, false)
|
||||
} else {
|
||||
fmt.Println(jnlp)
|
||||
return nil
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func showErrorAndExit(e error) {
|
||||
fmt.Fprintf(os.Stderr, "%s", e)
|
||||
fmt.Fprintln(os.Stderr)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
func newClient(options *BaseOptions) (redfish.IRedfishDriver, error) {
|
||||
func newClient() (redfish.IRedfishDriver, error) {
|
||||
if len(options.Endpoint) == 0 {
|
||||
return nil, fmt.Errorf("Missing endpoint")
|
||||
}
|
||||
@@ -104,7 +149,7 @@ func main() {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
e = parser.ParseArgs(os.Args[1:], false)
|
||||
options := parser.Options().(*BaseOptions)
|
||||
// options := parser.Options().(*BaseOptions)
|
||||
|
||||
if options.Help {
|
||||
fmt.Print(parser.HelpString())
|
||||
@@ -122,9 +167,11 @@ func main() {
|
||||
suboptions := subparser.Options()
|
||||
if options.SUBCOMMAND == "help" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else if options.SUBCOMMAND == "bmc-jnlp" {
|
||||
e = subcmd.Invoke(suboptions)
|
||||
} else {
|
||||
var client redfish.IRedfishDriver
|
||||
client, e = newClient(options)
|
||||
client, e = newClient()
|
||||
if e != nil {
|
||||
showErrorAndExit(e)
|
||||
}
|
||||
|
||||
@@ -1953,6 +1953,8 @@ func (b *SBaremetalInstance) GetConsoleJNLP(ctx context.Context) (string, error)
|
||||
return bmc.GetIdracConsoleJNLP(ctx, "", "")
|
||||
case "supermicro":
|
||||
return bmc.GetSupermicroConsoleJNLP(ctx)
|
||||
case "lenovo":
|
||||
return bmc.GetLenovoConsoleJNLP(ctx)
|
||||
}
|
||||
return "", httperrors.NewNotImplementedError("Unsupported manufacture %s", manufacture)
|
||||
}
|
||||
|
||||
@@ -20,9 +20,8 @@ import (
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/tristate"
|
||||
"yunion.io/x/pkg/util/stringutils"
|
||||
"yunion.io/x/pkg/utils"
|
||||
@@ -75,7 +74,7 @@ func (dev *MegaRaidPhyDev) ToBaremetalStorage(index int) *baremetal.BaremetalSto
|
||||
}
|
||||
|
||||
func (dev *MegaRaidPhyDev) GetSize() int64 {
|
||||
return dev.sector * int64(dev.block) / 1024 / 1024 // MB
|
||||
return dev.sector * dev.block / 1024 / 1024 // MB
|
||||
}
|
||||
|
||||
func (dev *MegaRaidPhyDev) parseLine(line string) bool {
|
||||
@@ -124,7 +123,7 @@ func (dev *MegaRaidPhyDev) parseLine(line string) bool {
|
||||
if err != nil {
|
||||
log.Errorf("parse logical sector size error: %v", err)
|
||||
dev.block = 512
|
||||
} else {
|
||||
} else if block > 0 {
|
||||
dev.block = int64(block)
|
||||
}
|
||||
default:
|
||||
@@ -189,6 +188,7 @@ type MegaRaidAdaptor struct {
|
||||
raid *MegaRaid
|
||||
devs []*MegaRaidPhyDev
|
||||
sn string
|
||||
name string
|
||||
busNumber string
|
||||
deviceNumber string
|
||||
funcNumber string
|
||||
@@ -209,6 +209,10 @@ func NewMegaRaidAdaptor(index int, raid *MegaRaid) (*MegaRaidAdaptor, error) {
|
||||
return adapter, nil
|
||||
}
|
||||
|
||||
func (adapter MegaRaidAdaptor) key() string {
|
||||
return adapter.name + adapter.sn
|
||||
}
|
||||
|
||||
func (adapter *MegaRaidAdaptor) fillInfo() error {
|
||||
cmd := GetCommand("-AdpAllInfo", fmt.Sprintf("-a%d", adapter.index))
|
||||
ret, err := adapter.remoteRun(cmd)
|
||||
@@ -223,10 +227,12 @@ func (adapter *MegaRaidAdaptor) fillInfo() error {
|
||||
switch key {
|
||||
case "Serial No":
|
||||
adapter.sn = val
|
||||
case "Product Name":
|
||||
adapter.name = val
|
||||
}
|
||||
}
|
||||
if len(adapter.sn) == 0 {
|
||||
return errors.New("Not found Serial No")
|
||||
if len(adapter.key()) == 0 {
|
||||
return errors.Error("Not found Serial No and Product Name")
|
||||
}
|
||||
return adapter.fillPCIInfo()
|
||||
}
|
||||
@@ -267,7 +273,7 @@ func (adapter *MegaRaidAdaptor) fillPCIInfo() error {
|
||||
}
|
||||
}
|
||||
if len(adapter.busNumber) == 0 || len(adapter.deviceNumber) == 0 || len(adapter.funcNumber) == 0 {
|
||||
return errors.New("Not found bus number")
|
||||
return errors.Error("Not found bus number")
|
||||
}
|
||||
pciDir := fmt.Sprintf("/sys/bus/pci/devices/0000:%s:%s.%s/", adapter.busNumber, adapter.deviceNumber, adapter.funcNumber)
|
||||
cmd = raiddrivers.GetCommand("ls", pciDir, "|", "grep", "host")
|
||||
@@ -601,18 +607,24 @@ func (adapter *MegaRaidAdaptor) BuildNoneRaid(devs []*baremetal.BaremetalStorage
|
||||
|
||||
type StorcliAdaptor struct {
|
||||
Controller int
|
||||
SN string
|
||||
sn string
|
||||
name string
|
||||
}
|
||||
|
||||
func newStorcliAdaptor() *StorcliAdaptor {
|
||||
return &StorcliAdaptor{
|
||||
Controller: -1,
|
||||
SN: "",
|
||||
sn: "",
|
||||
name: "",
|
||||
}
|
||||
}
|
||||
|
||||
func (a StorcliAdaptor) key() string {
|
||||
return a.name + a.sn
|
||||
}
|
||||
|
||||
func (a *StorcliAdaptor) isComplete() bool {
|
||||
return a.Controller >= 0 && a.SN != ""
|
||||
return a.Controller >= 0 && a.key() != ""
|
||||
}
|
||||
|
||||
func (a *StorcliAdaptor) parseLine(l string) {
|
||||
@@ -626,13 +638,15 @@ func (a *StorcliAdaptor) parseLine(l string) {
|
||||
case "Controller":
|
||||
a.Controller, _ = strconv.Atoi(val)
|
||||
case "Serial Number":
|
||||
a.SN = val
|
||||
a.sn = val
|
||||
case "Product Name":
|
||||
a.name = val
|
||||
}
|
||||
}
|
||||
|
||||
func (raid *MegaRaid) GetStorcliAdaptor() (map[string]*StorcliAdaptor, error) {
|
||||
ret := make(map[string]*StorcliAdaptor)
|
||||
cmd := GetCommand2("/call", "show", "|", "grep", "-iE", `'^(Controller|Serial Number)\s='`)
|
||||
cmd := GetCommand2("/call", "show", "|", "grep", "-iE", `'^(Controller|Product Name|Serial Number)\s='`)
|
||||
lines, err := raid.term.Run(cmd)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Get storcli adapter")
|
||||
@@ -641,7 +655,7 @@ func (raid *MegaRaid) GetStorcliAdaptor() (map[string]*StorcliAdaptor, error) {
|
||||
for _, l := range lines {
|
||||
adapter.parseLine(l)
|
||||
if adapter.isComplete() {
|
||||
ret[adapter.SN] = adapter
|
||||
ret[adapter.key()] = adapter
|
||||
adapter = newStorcliAdaptor()
|
||||
}
|
||||
}
|
||||
@@ -656,9 +670,9 @@ func (adapter *MegaRaidAdaptor) storcliCtrlIndex() (int, error) {
|
||||
if err != nil {
|
||||
return -1, errors.Wrap(err, "Get all Storcli adaptor")
|
||||
}
|
||||
storAdap, ok := storcliAdaps[adapter.sn]
|
||||
storAdap, ok := storcliAdaps[adapter.key()]
|
||||
if !ok {
|
||||
return -1, errors.Errorf("Not found storcli adaptor by SN %q", adapter.sn)
|
||||
return -1, errors.Errorf("Not found storcli adaptor by SN %q", adapter.key())
|
||||
}
|
||||
return storAdap.Controller, nil
|
||||
}
|
||||
@@ -914,6 +928,9 @@ func (raid *MegaRaid) ParsePhyDevs() error {
|
||||
if err != nil {
|
||||
return fmt.Errorf("List raid disk error: %v", err)
|
||||
}
|
||||
if raiddrivers.Debug {
|
||||
log.Debugf("-PDList -aALL: %s", ret)
|
||||
}
|
||||
err = raid.parsePhyDevs(ret)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parse physical disk device error: %v", err)
|
||||
|
||||
@@ -28,6 +28,10 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/sysutils"
|
||||
)
|
||||
|
||||
var (
|
||||
Debug bool
|
||||
)
|
||||
|
||||
const (
|
||||
MODULE_MEGARAID = "megaraid_sas"
|
||||
MODULE_HPSA = "hpsa"
|
||||
|
||||
@@ -58,7 +58,12 @@ func (self *BaremetalDeleteTask) OnInit(ctx context.Context, obj db.IStandaloneM
|
||||
}
|
||||
|
||||
func (self *BaremetalDeleteTask) OnDeleteBaremetalComplete(ctx context.Context, baremetal *models.SHost, body jsonutils.JSONObject) {
|
||||
baremetal.RealDelete(ctx, self.UserCred)
|
||||
err := baremetal.RealDelete(ctx, self.UserCred)
|
||||
if err != nil {
|
||||
log.Errorln("RealDelete fail %s", err)
|
||||
self.OnFailure(ctx, baremetal, jsonutils.Marshal(err))
|
||||
return
|
||||
}
|
||||
self.SetStageComplete(ctx, nil)
|
||||
}
|
||||
|
||||
|
||||
90
pkg/util/redfish/bmconsole/lenovo.go
Normal file
90
pkg/util/redfish/bmconsole/lenovo.go
Normal file
@@ -0,0 +1,90 @@
|
||||
// Copyright 2019 Yunion
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
package bmconsole
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/pkg/errors"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
)
|
||||
|
||||
func (r *SBMCConsole) GetLenovoConsoleJNLP(ctx context.Context) (string, error) {
|
||||
loginData := strings.Join([]string{
|
||||
"user=" + url.QueryEscape(r.username),
|
||||
"password=" + url.QueryEscape(r.password),
|
||||
}, "&")
|
||||
|
||||
// cookie:
|
||||
// _appwebSessionId_=09eb9a178d520d2c9fa1430dd355dc27; path=/; httponly; secure
|
||||
|
||||
cookies := make(map[string]string)
|
||||
cookies["_appwebSessionId_"] = ""
|
||||
|
||||
// first do html login
|
||||
postHdr := http.Header{}
|
||||
postHdr.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
postHdr.Set("Referer", fmt.Sprintf("https://%s/login.html", r.host))
|
||||
setCookieHeader(postHdr, cookies)
|
||||
hdr, _, err := r.RawRequest(ctx, httputils.POST, "/data/login", postHdr, []byte(loginData))
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "r.FormPost Login")
|
||||
}
|
||||
for _, cookieHdr := range hdr["Set-Cookie"] {
|
||||
parts := strings.Split(cookieHdr, ";")
|
||||
if len(parts) > 0 {
|
||||
pparts := strings.Split(parts[0], "=")
|
||||
if len(pparts) > 1 {
|
||||
cookies[pparts[0]] = pparts[1]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
getHdr := http.Header{}
|
||||
getHdr.Set("Referer", fmt.Sprintf("https://%s/bmctree.html", r.host))
|
||||
setCookieHeader(getHdr, cookies)
|
||||
_, launchResp, err := r.RawRequest(ctx, httputils.GET, "/vkvmLaunch.html", getHdr, nil)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "Get vkvmLauch.html")
|
||||
}
|
||||
|
||||
var token string
|
||||
st3Pattern := regexp.MustCompile(`<input type="hidden" name="ST3" value="(\w+)">`)
|
||||
matched := st3Pattern.FindAllStringSubmatch(string(launchResp), -1)
|
||||
if len(matched) > 0 && len(matched[0]) > 1 {
|
||||
token = matched[0][1]
|
||||
}
|
||||
|
||||
if len(token) == 0 {
|
||||
return "", errors.Wrap(httperrors.ErrBadRequest, "no valid ST3 token")
|
||||
}
|
||||
|
||||
path := fmt.Sprintf("viewer.jnlp(%s@0@%d)", r.host, time.Now().UnixNano()/1000000)
|
||||
body := "ST3=" + url.QueryEscape(token)
|
||||
getHdr.Set("Referer", fmt.Sprintf("https://%s/vkvmLaunch.html", r.host))
|
||||
_, rspBody, err := r.RawRequest(ctx, httputils.POST, path, getHdr, []byte(body))
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "r.RawGet %s", path)
|
||||
}
|
||||
return string(rspBody), nil
|
||||
}
|
||||
@@ -16,14 +16,12 @@ package bmconsole
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/util/timeutils"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/util/httputils"
|
||||
)
|
||||
@@ -44,6 +42,7 @@ func (r *SBMCConsole) GetSupermicroConsoleJNLP(ctx context.Context) (string, err
|
||||
// first do html login
|
||||
postHdr := http.Header{}
|
||||
postHdr.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
postHdr.Set("Referer", fmt.Sprintf("http://%s/", r.host))
|
||||
setCookieHeader(postHdr, cookies)
|
||||
hdr, _, err := r.RawRequest(ctx, httputils.POST, "/cgi/login.cgi", postHdr, []byte(loginData))
|
||||
if err != nil {
|
||||
@@ -60,11 +59,12 @@ func (r *SBMCConsole) GetSupermicroConsoleJNLP(ctx context.Context) (string, err
|
||||
}
|
||||
|
||||
getHdr := http.Header{}
|
||||
getHdr.Set("Referer", fmt.Sprintf("https://%s/cgi/url_redirect.cgi?url_name=man_ikvm", r.host))
|
||||
setCookieHeader(getHdr, cookies)
|
||||
|
||||
now := time.Now()
|
||||
// now := time.Now()
|
||||
// fwtype=255&time_stamp=Thu%20Apr%2023%202020%2002%3A25%3A13%20GMT%2B0800%20(%E4%B8%AD%E5%9B%BD%E6%A0%87%E5%87%86%E6%97%B6%E9%97%B4)&_=
|
||||
loginData = strings.Join([]string{
|
||||
/*loginData = strings.Join([]string{
|
||||
"fwtype=255",
|
||||
"time_stamp=" + url.QueryEscape(timeutils.RFC2882Time(now)),
|
||||
"_=",
|
||||
@@ -78,8 +78,9 @@ func (r *SBMCConsole) GetSupermicroConsoleJNLP(ctx context.Context) (string, err
|
||||
if r.isDebug {
|
||||
log.Debugf("upgrade_process.cgi %s", rspBody)
|
||||
}
|
||||
*/
|
||||
|
||||
_, rspBody, err = r.RawRequest(ctx, httputils.GET, "/cgi/url_redirect.cgi?url_name=ikvm&url_type=jwsk", getHdr, nil)
|
||||
_, rspBody, err := r.RawRequest(ctx, httputils.GET, "/cgi/url_redirect.cgi?url_name=ikvm&url_type=jwsk", getHdr, nil)
|
||||
if err != nil {
|
||||
return "", errors.Wrap(err, "r.RawGet")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user