Skip to content

Commit

Permalink
feat(climc): migrate pod port_mappings to guestnetwork (#20515)
Browse files Browse the repository at this point in the history
  • Loading branch information
zexi authored Jun 11, 2024
1 parent 66b9bb3 commit 15cc91c
Show file tree
Hide file tree
Showing 5 changed files with 123 additions and 1 deletion.
89 changes: 89 additions & 0 deletions cmd/climc/shell/compute/server_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ package compute
import (
"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/sets"

computeapi "yunion.io/x/onecloud/pkg/apis/compute"
"yunion.io/x/onecloud/pkg/mcclient"
modules "yunion.io/x/onecloud/pkg/mcclient/modules/compute"
options "yunion.io/x/onecloud/pkg/mcclient/options/compute"
Expand Down Expand Up @@ -71,4 +73,91 @@ func init() {
}
return modules.Containers.Exec(s, ctrId, opt.ToAPIInput())
})

type MigratePortMappingsOptions struct {
options.ServerIdOptions
RemovePort []int `help:"remove port"`
RemoteIp []string `help:"remote ips"`
}
R(&MigratePortMappingsOptions{}, "pod-migrate-port-mappings", "Migrate port mappings to nic", func(s *mcclient.ClientSession, opt *MigratePortMappingsOptions) error {
sObj, err := modules.Servers.Get(s, opt.ID, nil)
if err != nil {
return err
}
id, err := sObj.GetString("id")
if err != nil {
return errors.Wrapf(err, "get server id from %s", sObj)
}
metadata, err := modules.Servers.GetMetadata(s, id, nil)
if err != nil {
return err
}
pmStr, err := metadata.GetString(computeapi.POD_METADATA_PORT_MAPPINGS)
if err != nil {
return err
}
pms, err := jsonutils.ParseString(pmStr)
if err != nil {
return err
}
pmObjs := []computeapi.PodPortMapping{}
if err := pms.Unmarshal(&pmObjs); err != nil {
return errors.Wrapf(err, "unmarshal %s to port_mappings", pms)
}
if len(opt.RemovePort) > 0 {
pp := sets.NewInt(opt.RemovePort...)
newPmObjs := []computeapi.PodPortMapping{}
for _, pm := range pmObjs {
if pp.Has(pm.ContainerPort) {
continue
}
tmpPm := pm
newPmObjs = append(newPmObjs, tmpPm)
}
pmObjs = newPmObjs
}
nicPm := make([]*computeapi.GuestPortMapping, len(pmObjs))
for i, pm := range pmObjs {
nicPm[i] = &computeapi.GuestPortMapping{
Protocol: computeapi.GuestPortMappingProtocol(pm.Protocol),
Port: pm.ContainerPort,
HostPort: pm.HostPort,
HostIp: pm.HostIp,
RemoteIps: opt.RemoteIp,
}
if pm.HostPortRange != nil {
nicPm[i].HostPortRange = &computeapi.GuestPortMappingPortRange{
Start: pm.HostPortRange.Start,
End: pm.HostPortRange.End,
}
}
}
params := jsonutils.Marshal(map[string]interface{}{
"scope": "system",
"details": true,
})
sNets, err := modules.Servernetworks.ListDescendent(s, id, params)
if err != nil {
return errors.Wrap(err, "list server networks")
}
if len(sNets.Data) == 0 {
return errors.Errorf("no server networks found")
}
firstNet := sNets.Data[0]
sNet := new(computeapi.GuestnetworkDetails)
if err := firstNet.Unmarshal(sNet); err != nil {
return errors.Wrap(err, "unmarshal to guestnetwork details")
}

updateData := jsonutils.Marshal(map[string]interface{}{
"port_mappings": nicPm,
})
obj, err := modules.Servernetworks.Update(s, sNet.GuestId, sNet.NetworkId, nil, updateData)
if err != nil {
return errors.Wrap(err, "update server networks")
}
printObject(obj)

return nil
})
}
3 changes: 2 additions & 1 deletion pkg/apis/compute/guestnetwork.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@ type GuestnetworkUpdateInput struct {

Index *int8 `json:"index"`

IsDefault *bool `json:"is_default"`
IsDefault *bool `json:"is_default"`
PortMappings GuestPortMappings `json:"port_mappings"`
}

type GuestnetworkBaseDesc struct {
Expand Down
4 changes: 4 additions & 0 deletions pkg/apis/compute/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,7 @@ type PodMetadataPortMapping struct {
HostPort int32 `json:"host_port,omitempty"`
HostIp string `json:"host_ip"`
}

type GuestSetPortMappingsInput struct {
PortMappings []*PodPortMapping `json:"port_mappings"`
}
6 changes: 6 additions & 0 deletions pkg/compute/models/guestnetworks.go
Original file line number Diff line number Diff line change
Expand Up @@ -843,6 +843,12 @@ func (gn *SGuestnetwork) ValidateUpdateData(
return input, errors.Wrap(httperrors.ErrInvalidStatus, "nic of default gateway has no ip")
}
}
for _, pm := range input.PortMappings {
if err := validatePortMapping(pm); err != nil {
return input, err
}
}

var err error
input.GuestJointBaseUpdateInput, err = gn.SGuestJointsBase.ValidateUpdateData(ctx, userCred, query, input.GuestJointBaseUpdateInput)
if err != nil {
Expand Down
22 changes: 22 additions & 0 deletions pkg/mcclient/options/compute/server_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"strconv"
"strings"

"yunion.io/x/jsonutils"
"yunion.io/x/pkg/errors"
"yunion.io/x/pkg/util/fileutils"
"yunion.io/x/pkg/util/regutils"
Expand Down Expand Up @@ -252,3 +253,24 @@ type PodExecOptions struct {
Scope string `help:"Scope of containers query" choices:"system|domain|project"`
Container string `help:"Container name. If omitted, use the first container." short-token:"c"`
}

type PodSetPortMappingOptions struct {
ServerIdOptions
PortMapping []string `help:"Port mapping of the pod and the format is: host_port=8080,port=80,protocol=<tcp|udp>,host_port_range=<int>-<int>" short-token:"p"`
}

func (o *PodSetPortMappingOptions) Params() (jsonutils.JSONObject, error) {
portMappings := make([]*computeapi.PodPortMapping, 0)
if len(o.PortMapping) != 0 {
for _, input := range o.PortMapping {
pm, err := ParsePodPortMapping(input)
if err != nil {
return nil, errors.Wrapf(err, "parse port mapping: %s", input)
}
portMappings = append(portMappings, pm)
}
}
return jsonutils.Marshal(&computeapi.GuestSetPortMappingsInput{
PortMappings: portMappings,
}), nil
}

0 comments on commit 15cc91c

Please sign in to comment.