Automatic merge from release/2.1.0 -> release/2.2.0

* commit '62e269b20f3639fd21a9aeb986bbe89959aef60c':
  webconsole: support baremetal ipmitool sol
This commit is contained in:
李泽玺
2018-09-06 19:32:11 +08:00
6 changed files with 145 additions and 16 deletions
+14 -5
View File
@@ -12,12 +12,12 @@ import (
)
func init() {
handleResult := func(opt o.WebConsoleFrontendOptions, obj jsonutils.JSONObject) error {
if opt.WebUrl == "" {
handleResult := func(opt o.WebConsoleOptions, obj jsonutils.JSONObject) error {
if opt.WebconsoleUrl == "" {
printObject(obj)
return nil
}
u, err := url.Parse(opt.WebUrl)
u, err := url.Parse(opt.WebconsoleUrl)
if err != nil {
return err
}
@@ -40,7 +40,7 @@ func init() {
if err != nil {
return err
}
handleResult(args.WebConsoleFrontendOptions, ret)
handleResult(args.WebConsoleOptions, ret)
return nil
})
@@ -53,7 +53,16 @@ func init() {
if err != nil {
return err
}
handleResult(args.WebConsoleFrontendOptions, ret)
handleResult(args.WebConsoleOptions, ret)
return nil
})
R(&o.WebConsoleBaremetalOptions{}, "webconsole-baremetal", "Connect baremetal host webconsole", func(s *mcclient.ClientSession, args *o.WebConsoleBaremetalOptions) error {
ret, err := modules.WebConsole.DoBaremetalConnect(s, args.ID)
if err != nil {
return err
}
handleResult(args.WebConsoleOptions, ret)
return nil
})
}
+4
View File
@@ -63,3 +63,7 @@ func (m WebConsoleManager) DoK8sLogConnect(
) (jsonutils.JSONObject, error) {
return m.DoK8sConnect(s, id, "log", params)
}
func (m WebConsoleManager) DoBaremetalConnect(s *mcclient.ClientSession, id string) (jsonutils.JSONObject, error) {
return m.DoConnect(s, "baremetal", id, "", nil)
}
+12 -3
View File
@@ -4,12 +4,12 @@ import (
"yunion.io/x/jsonutils"
)
type WebConsoleFrontendOptions struct {
WebUrl string `help:"Frontend terminal HTML web url" short-token:"w"`
type WebConsoleOptions struct {
WebconsoleUrl string `help:"Frontend webconsole url" short-token:"w" default:"$WEBCONSOLE_URL"`
}
type PodBaseOptions struct {
WebConsoleFrontendOptions
WebConsoleOptions
NAME string `help:"Name of k8s pod to connect"`
Namespace string `help:"Namespace of this pod"`
Container string `help:"Container in this pod"`
@@ -27,3 +27,12 @@ type PodShellOptions struct {
type PodLogOptoins struct {
PodBaseOptions
}
type WebConsoleBaremetalOptions struct {
WebConsoleOptions
ID string `help:"Baremetal host id or name"`
}
func (opt *WebConsoleBaremetalOptions) Params() (*jsonutils.JSONDict, error) {
return StructToParams(opt)
}
+49
View File
@@ -0,0 +1,49 @@
package command
import (
"fmt"
"os/exec"
)
type IpmiInfo struct {
IpAddr string `json:"ip_addr"`
Username string `json:"username"`
Password string `json:"password"`
Present bool `json:"present"`
}
type IpmitoolSol struct {
*BaseCommand
Info *IpmiInfo
}
func NewIpmitoolSolCommand(info *IpmiInfo) (*IpmitoolSol, error) {
if info.IpAddr == "" {
return nil, fmt.Errorf("Empty host ip address")
}
if info.Username == "" {
return nil, fmt.Errorf("Empty username")
}
if info.Password == "" {
return nil, fmt.Errorf("Empty password")
}
name := "ipmitool"
cmd := NewBaseCommand(name, "-I", "lanplus")
cmd.AppendArgs("-H", info.IpAddr)
cmd.AppendArgs("-U", info.Username)
cmd.AppendArgs("-P", info.Password)
cmd.AppendArgs("sol", "activate")
tool := &IpmitoolSol{
BaseCommand: cmd,
Info: info,
}
return tool, nil
}
func (c *IpmitoolSol) GetCommand() *exec.Cmd {
return c.BaseCommand.GetCommand()
}
func (c IpmitoolSol) GetProtocol() string {
return PROTOCOL_TTY
}
+65 -8
View File
@@ -13,7 +13,9 @@ import (
"yunion.io/x/onecloud/pkg/appctx"
"yunion.io/x/onecloud/pkg/appsrv"
"yunion.io/x/onecloud/pkg/httperrors"
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/mcclient/modules"
"yunion.io/x/onecloud/pkg/mcclient/modules/k8s"
"yunion.io/x/onecloud/pkg/webconsole/command"
o "yunion.io/x/onecloud/pkg/webconsole/options"
@@ -28,6 +30,7 @@ const (
func InitHandlers(app *appsrv.Application) {
app.AddHandler("POST", ApiPathPrefix+"k8s/<podName>/shell", auth.Authenticate(handleK8sShell))
app.AddHandler("POST", ApiPathPrefix+"k8s/<podName>/log", auth.Authenticate(handleK8sLog))
app.AddHandler("POST", ApiPathPrefix+"baremetal/<id>", auth.Authenticate(handleBaremetalShell))
}
func fetchEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (map[string]string, jsonutils.JSONObject, jsonutils.JSONObject) {
@@ -105,6 +108,30 @@ func fetchK8sEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (*
}, nil
}
type CloudEnv struct {
ClientSessin *mcclient.ClientSession
Params map[string]string
Query jsonutils.JSONObject
Body jsonutils.JSONObject
Ctx context.Context
}
func fetchCloudEnv(ctx context.Context, w http.ResponseWriter, r *http.Request) (*CloudEnv, error) {
params, query, body := fetchEnv(ctx, w, r)
userCred := auth.FetchUserCredential(ctx)
if userCred == nil {
return nil, httperrors.NewUnauthorizedError("No token founded")
}
s := auth.Client().NewSession(o.Options.Region, "", "internal", userCred, "")
return &CloudEnv{
ClientSessin: s,
Params: params,
Query: query,
Body: body,
Ctx: ctx,
}, nil
}
func handleK8sCommand(
ctx context.Context,
w http.ResponseWriter,
@@ -118,6 +145,44 @@ func handleK8sCommand(
}
cmd := cmdFactory(env.KubeConfig, env.Namespace, env.Pod, env.Container)
handleCommandSession(cmd, w)
}
func handleK8sShell(ctx context.Context, w http.ResponseWriter, r *http.Request) {
handleK8sCommand(ctx, w, r, command.NewPodBashCommand)
}
func handleK8sLog(ctx context.Context, w http.ResponseWriter, r *http.Request) {
handleK8sCommand(ctx, w, r, command.NewPodLogCommand)
}
func handleBaremetalShell(ctx context.Context, w http.ResponseWriter, r *http.Request) {
env, err := fetchCloudEnv(ctx, w, r)
if err != nil {
httperrors.GeneralServerError(w, err)
return
}
hostId := env.Params["<id>"]
ret, err := modules.Hosts.GetSpecific(env.ClientSessin, hostId, "ipmi", nil)
if err != nil {
httperrors.GeneralServerError(w, err)
return
}
info := command.IpmiInfo{}
err = ret.Unmarshal(&info)
if err != nil {
httperrors.GeneralServerError(w, err)
return
}
cmd, err := command.NewIpmitoolSolCommand(&info)
if err != nil {
httperrors.GeneralServerError(w, err)
return
}
handleCommandSession(cmd, w)
}
func handleCommandSession(cmd command.ICommand, w http.ResponseWriter) {
cmdSession, err := session.Manager.Save(cmd)
if err != nil {
httperrors.GeneralServerError(w, err)
@@ -134,14 +199,6 @@ func handleK8sCommand(
sendJSON(w, data)
}
func handleK8sShell(ctx context.Context, w http.ResponseWriter, r *http.Request) {
handleK8sCommand(ctx, w, r, command.NewPodBashCommand)
}
func handleK8sLog(ctx context.Context, w http.ResponseWriter, r *http.Request) {
handleK8sCommand(ctx, w, r, command.NewPodLogCommand)
}
func sendJSON(w http.ResponseWriter, body jsonutils.JSONObject) {
ret := jsonutils.NewDict()
if body != nil {
+1
View File
@@ -25,6 +25,7 @@ func NewPty(session *SSession) (p *Pty, err error) {
Session: session,
Cmd: cmd,
}
log.Debugf("[session %s] Start command: %#v", session.Id, cmd)
p.Pty, err = pty.Start(p.Cmd)
if err != nil {
return