mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
fix(webconsole): support host ssh (#19387)
This commit is contained in:
@@ -75,8 +75,9 @@ type WebConsoleSshOptions struct {
|
||||
Ip string `help:"IP to connect if multiple IPs on server"`
|
||||
Port int `help:"Remote server port"`
|
||||
Username string `help:"Remote server username"`
|
||||
KeepUsername bool `help:"Keep remove username`
|
||||
KeepUsername bool `help:"Keep remove username"`
|
||||
Password string `help:"Remote server password"`
|
||||
ResourceType string `help:"Resource Type" choices:"host|server"`
|
||||
}
|
||||
|
||||
func (opt *WebConsoleSshOptions) Params() (*jsonutils.JSONDict, error) {
|
||||
|
||||
@@ -186,14 +186,54 @@ func handleSshShell(ctx context.Context, w http.ResponseWriter, r *http.Request)
|
||||
}
|
||||
idStr := env.Params["<ip>"]
|
||||
if !regutils.MatchIPAddr(idStr) {
|
||||
ip, port, guestDetails, err := session.ResolveServerSSHIPPortById(ctx, env.ClientSessin, idStr, sshConnInfo.IP, sshConnInfo.Port)
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
var tryServer = func() error {
|
||||
ip, port, guestDetails, err := session.ResolveServerSSHIPPortById(ctx, env.ClientSessin, idStr, sshConnInfo.IP, sshConnInfo.Port)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sshConnInfo.IP = ip
|
||||
sshConnInfo.Port = port
|
||||
sshConnInfo.GuestDetails = guestDetails
|
||||
return nil
|
||||
}
|
||||
var tryHost = func() error {
|
||||
ip, port, hostDetails, err := session.ResolveHostSSHIPPortById(ctx, env.ClientSessin, idStr, sshConnInfo.IP, sshConnInfo.Port)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sshConnInfo.IP = ip
|
||||
sshConnInfo.Port = port
|
||||
sshConnInfo.HostDetails = hostDetails
|
||||
return nil
|
||||
}
|
||||
switch sshConnInfo.ResourceType {
|
||||
case "server":
|
||||
err = tryServer()
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
return
|
||||
}
|
||||
case "host":
|
||||
err = tryHost()
|
||||
if err != nil {
|
||||
httperrors.GeneralServerError(ctx, w, err)
|
||||
return
|
||||
}
|
||||
default:
|
||||
for _, try := range []func() error{
|
||||
tryServer,
|
||||
tryHost,
|
||||
} {
|
||||
err = try()
|
||||
if err == nil {
|
||||
s := session.NewSshSession(ctx, env.ClientSessin, sshConnInfo)
|
||||
handleSshSession(ctx, s, w)
|
||||
return
|
||||
}
|
||||
}
|
||||
httperrors.NewResourceNotFoundError("%s not found", idStr)
|
||||
return
|
||||
}
|
||||
sshConnInfo.IP = ip
|
||||
sshConnInfo.Port = port
|
||||
sshConnInfo.GuestDetails = guestDetails
|
||||
} else {
|
||||
// directly ssh IP should be deprecated gradually
|
||||
sshConnInfo.IP = idStr
|
||||
|
||||
@@ -51,6 +51,13 @@ func (dispInfo *SDisplayInfo) fetchGuestInfo(guestDetails *compute_api.ServerDet
|
||||
dispInfo.Ips = guestDetails.IPs
|
||||
}
|
||||
|
||||
func (dispInfo *SDisplayInfo) fetchHostInfo(hostDetails *compute_api.HostDetails) {
|
||||
dispInfo.Hypervisor = hostDetails.HostType
|
||||
dispInfo.OsArch = hostDetails.CpuArchitecture
|
||||
dispInfo.InstanceName = hostDetails.Name
|
||||
dispInfo.Ips = hostDetails.AccessIp
|
||||
}
|
||||
|
||||
func (dispInfo *SDisplayInfo) populateParams(params url.Values) url.Values {
|
||||
if options.Options.EnableWatermark && len(dispInfo.WaterMark) > 0 {
|
||||
params["water_mark"] = []string{dispInfo.WaterMark}
|
||||
@@ -123,3 +130,16 @@ func FetchServerInfo(ctx context.Context, s *mcclient.ClientSession, sid string)
|
||||
}
|
||||
return &guestDetails, nil
|
||||
}
|
||||
|
||||
func FetchHostInfo(ctx context.Context, s *mcclient.ClientSession, id string) (*compute_api.HostDetails, error) {
|
||||
hostInfo, err := compute.Hosts.Get(s, id, nil)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "GetById %s", id)
|
||||
}
|
||||
hostDetails := compute_api.HostDetails{}
|
||||
err = hostInfo.Unmarshal(&hostDetails)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "Unmarshal guest info")
|
||||
}
|
||||
return &hostDetails, nil
|
||||
}
|
||||
|
||||
@@ -36,8 +36,10 @@ type SSshConnectionInfo struct {
|
||||
KeepUsername bool `json:"keep_username"`
|
||||
Password string `json:"password"`
|
||||
Name string `json:"name"`
|
||||
ResourceType string `json:"resource_type" choices:"host|server"`
|
||||
|
||||
GuestDetails *compute_api.ServerDetails
|
||||
HostDetails *compute_api.HostDetails
|
||||
}
|
||||
|
||||
func ResolveServerSSHIPPortById(ctx context.Context, s *mcclient.ClientSession, id string, ip string, port int) (string, int, *compute_api.ServerDetails, error) {
|
||||
@@ -125,6 +127,18 @@ func resolveServerIPPortById(ctx context.Context, s *mcclient.ClientSession, id
|
||||
return ip, port, guestDetails, nil
|
||||
}
|
||||
|
||||
func ResolveHostSSHIPPortById(ctx context.Context, s *mcclient.ClientSession, id string, ip string, port int) (string, int, *compute_api.HostDetails, error) {
|
||||
if port <= 0 {
|
||||
port = 22
|
||||
}
|
||||
|
||||
hostDetails, err := FetchHostInfo(ctx, s, id)
|
||||
if err != nil {
|
||||
return "", 0, nil, errors.Wrap(err, "fetchServerInfo")
|
||||
}
|
||||
return hostDetails.AccessIp, port, hostDetails, nil
|
||||
}
|
||||
|
||||
type sForwardInfo struct {
|
||||
ProxyAddr string `json:"proxy_addr"`
|
||||
ProxyPort int `json:"proxy_port"`
|
||||
|
||||
@@ -51,6 +51,7 @@ type SSshSession struct {
|
||||
Password string
|
||||
|
||||
guestDetails *compute_api.ServerDetails
|
||||
hostDetails *compute_api.HostDetails
|
||||
}
|
||||
|
||||
func NewSshSession(ctx context.Context, us *mcclient.ClientSession, conn SSshConnectionInfo) *SSshSession {
|
||||
@@ -65,6 +66,7 @@ func NewSshSession(ctx context.Context, us *mcclient.ClientSession, conn SSshCon
|
||||
Password: conn.Password,
|
||||
|
||||
guestDetails: conn.GuestDetails,
|
||||
hostDetails: conn.HostDetails,
|
||||
}
|
||||
if conn.Port <= 0 {
|
||||
ret.Port = 22
|
||||
@@ -147,6 +149,8 @@ func (s *SSshSession) GetDisplayInfo(ctx context.Context) (*SDisplayInfo, error)
|
||||
dispInfo.WaterMark = fetchWaterMark(userInfo)
|
||||
if s.guestDetails != nil {
|
||||
dispInfo.fetchGuestInfo(s.guestDetails)
|
||||
} else if s.hostDetails != nil {
|
||||
dispInfo.fetchHostInfo(s.hostDetails)
|
||||
} else {
|
||||
dispInfo.Ips = s.Host
|
||||
if len(s.name) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user