feat(host): guestman: add {Open,Close,List}Forward handler

This commit is contained in:
Yousong Zhou
2020-12-15 22:12:23 +08:00
parent eb6febcc16
commit daf863bd44
5 changed files with 218 additions and 0 deletions
+1
View File
@@ -0,0 +1 @@
package forwarder // import "yunion.io/x/onecloud/pkg/hostman/guestman/forwarder"
@@ -0,0 +1,64 @@
// 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 guesthandlers
import (
"context"
"yunion.io/x/jsonutils"
hostapis "yunion.io/x/onecloud/pkg/apis/host"
"yunion.io/x/onecloud/pkg/hostman/guestman"
"yunion.io/x/onecloud/pkg/httperrors"
)
func guestOpenForward(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
req := &hostapis.GuestOpenForwardRequest{}
if err := body.Unmarshal(req); err != nil {
return nil, httperrors.NewInputParameterError("unmarshal: %v", err)
}
gm := guestman.GetGuestManager()
resp, err := gm.OpenForward(ctx, sid, req)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
return jsonutils.Marshal(resp), nil
}
func guestListForward(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
req := &hostapis.GuestListForwardRequest{}
if err := body.Unmarshal(req); err != nil {
return nil, httperrors.NewInputParameterError("unmarshal: %v", err)
}
gm := guestman.GetGuestManager()
resp, err := gm.ListForward(ctx, sid, req)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
return jsonutils.Marshal(resp), nil
}
func guestCloseForward(ctx context.Context, sid string, body jsonutils.JSONObject) (interface{}, error) {
req := &hostapis.GuestCloseForwardRequest{}
if err := body.Unmarshal(req); err != nil {
return nil, httperrors.NewInputParameterError("unmarshal: %v", err)
}
gm := guestman.GetGuestManager()
resp, err := gm.CloseForward(ctx, sid, req)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
return jsonutils.Marshal(resp), nil
}
@@ -77,6 +77,9 @@ func AddGuestTaskHandler(prefix string, app *appsrv.Application) {
"cancel-block-jobs": guestCancelBlockJobs,
"create-from-libvirt": guestCreateFromLibvirt,
"create-form-esxi": guestCreateFromEsxi,
"open-forward": guestOpenForward,
"list-forward": guestListForward,
"close-forward": guestCloseForward,
} {
app.AddHandler("POST",
fmt.Sprintf("%s/%s/<sid>/%s", prefix, keyWord, action),
+149
View File
@@ -33,7 +33,10 @@ import (
"yunion.io/x/pkg/util/seclib"
"yunion.io/x/onecloud/pkg/apis/compute"
hostapi "yunion.io/x/onecloud/pkg/apis/host"
"yunion.io/x/onecloud/pkg/appsrv"
fwd "yunion.io/x/onecloud/pkg/hostman/guestman/forwarder"
fwdpb "yunion.io/x/onecloud/pkg/hostman/guestman/forwarder/api"
"yunion.io/x/onecloud/pkg/hostman/guestman/types"
deployapi "yunion.io/x/onecloud/pkg/hostman/hostdeployer/apis"
"yunion.io/x/onecloud/pkg/hostman/hostutils"
@@ -382,6 +385,152 @@ func (m *SGuestManager) Monitor(sid, cmd string, callback func(string)) error {
}
}
func (m *SGuestManager) sdnClient() (fwdpb.ForwarderClient, error) {
sockPath := options.HostOptions.SdnSocketPath
if strings.HasPrefix(sockPath, "/") {
sockPath = "unix://" + sockPath
}
cli, err := fwd.NewClient(sockPath)
return cli, err
}
func (m *SGuestManager) OpenForward(ctx context.Context, sid string, req *hostapi.GuestOpenForwardRequest) (*hostapi.GuestOpenForwardResponse, error) {
guest, ok := m.GetServer(sid)
if !ok {
return nil, httperrors.NewNotFoundError("Not found")
}
if !guest.IsRunning() {
return nil, httperrors.NewBadRequestError("Server stopped??")
}
nic := guest.GetVpcNIC()
if nic == nil {
return nil, httperrors.NewBadRequestError("no vpc nic")
}
netId, _ := nic.GetString("net_id")
if netId == "" {
return nil, httperrors.NewBadRequestError("no network id")
}
ip, _ := nic.GetString("ip")
if ip == "" {
return nil, httperrors.NewBadRequestError("no vpc ip")
}
pbreq := &fwdpb.OpenRequest{
NetId: netId,
Proto: req.Proto,
BindAddr: m.host.GetMasterIp(),
RemoteAddr: ip,
RemotePort: uint32(req.Port),
}
cli, err := m.sdnClient()
if err != nil {
log.Errorf("new sdn client error: %v", err)
return nil, httperrors.NewBadGatewayError("lost sdn connection")
}
resp, err := cli.Open(ctx, pbreq)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
output := &hostapi.GuestOpenForwardResponse{
Proto: resp.Proto,
Addr: resp.RemoteAddr,
Port: int(resp.RemotePort),
ProxyAddr: resp.BindAddr,
ProxyPort: int(resp.BindPort),
}
return output, nil
}
func (m *SGuestManager) CloseForward(ctx context.Context, sid string, req *hostapi.GuestCloseForwardRequest) (*hostapi.GuestCloseForwardResponse, error) {
guest, ok := m.GetServer(sid)
if !ok {
return nil, httperrors.NewNotFoundError("Not found")
}
nic := guest.GetVpcNIC()
if nic == nil {
return nil, httperrors.NewBadRequestError("no vpc nic")
}
netId, _ := nic.GetString("net_id")
if netId == "" {
return nil, httperrors.NewBadRequestError("no network id")
}
pbreq := &fwdpb.CloseRequest{
NetId: netId,
Proto: req.Proto,
BindAddr: req.ProxyAddr,
BindPort: uint32(req.ProxyPort),
}
cli, err := m.sdnClient()
if err != nil {
log.Errorf("new sdn client error: %v", err)
return nil, httperrors.NewBadGatewayError("lost sdn connection")
}
resp, err := cli.Close(ctx, pbreq)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
output := &hostapi.GuestCloseForwardResponse{
Proto: resp.Proto,
ProxyAddr: resp.BindAddr,
ProxyPort: int(resp.BindPort),
}
return output, nil
}
func (m *SGuestManager) ListForward(ctx context.Context, sid string, req *hostapi.GuestListForwardRequest) (*hostapi.GuestListForwardResponse, error) {
guest, ok := m.GetServer(sid)
if !ok {
return nil, httperrors.NewNotFoundError("Not found")
}
if !guest.IsRunning() {
return nil, httperrors.NewBadRequestError("Server stopped??")
}
nic := guest.GetVpcNIC()
if nic == nil {
return nil, httperrors.NewBadRequestError("no vpc nic")
}
netId, _ := nic.GetString("net_id")
if netId == "" {
return nil, httperrors.NewBadRequestError("no network id")
}
pbreq := &fwdpb.ListByRemoteRequest{
NetId: netId,
Proto: req.Proto,
RemoteAddr: req.Addr,
RemotePort: uint32(req.Port),
}
cli, err := m.sdnClient()
if err != nil {
log.Errorf("new sdn client error: %v", err)
return nil, httperrors.NewBadGatewayError("lost sdn connection")
}
resp, err := cli.ListByRemote(ctx, pbreq)
if err != nil {
return nil, httperrors.NewGeneralError(err)
}
var outputForwards []hostapi.GuestOpenForwardResponse
for i := range resp.Forwards {
outputForwards = append(outputForwards, hostapi.GuestOpenForwardResponse{
Proto: resp.Forwards[i].Proto,
Addr: resp.Forwards[i].RemoteAddr,
Port: int(resp.Forwards[i].RemotePort),
ProxyAddr: resp.Forwards[i].BindAddr,
ProxyPort: int(resp.Forwards[i].BindPort),
})
}
output := &hostapi.GuestListForwardResponse{
Forwards: outputForwards,
}
return output, nil
}
func (m *SGuestManager) GuestCreate(ctx context.Context, params interface{}) (jsonutils.JSONObject, error) {
deployParams, ok := params.(*SGuestDeploy)
if !ok {
+1
View File
@@ -0,0 +1 @@
package types // import "yunion.io/x/onecloud/pkg/hostman/guestman/types"