mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-19 10:46:58 +08:00
fix: bond interface missing default gateway (#19952)
Co-authored-by: Qiu Jian <qiujian@yunionyun.com>
This commit is contained in:
@@ -94,6 +94,7 @@ func init() {
|
||||
Driver string `help:"Driver model of vNIC" choices:"virtio|e1000|vmxnet3|rtl8139"`
|
||||
Index int64 `help:"Index of NIC" default:"-1"`
|
||||
Ifname string `help:"Interface name of vNIC on host"`
|
||||
Default bool `help:"is default nic?"`
|
||||
}
|
||||
R(&ServerNetworkUpdateOptions{}, "server-network-update", "Update server network settings", func(s *mcclient.ClientSession, args *ServerNetworkUpdateOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
@@ -106,6 +107,9 @@ func init() {
|
||||
if len(args.Ifname) > 0 {
|
||||
params.Add(jsonutils.NewString(args.Ifname), "ifname")
|
||||
}
|
||||
if args.Default {
|
||||
params.Add(jsonutils.JSONTrue, "is_default")
|
||||
}
|
||||
if params.Size() == 0 {
|
||||
return InvalidUpdateError()
|
||||
}
|
||||
|
||||
@@ -644,12 +644,13 @@ func (f *ResourceHandlers) updateJointHandler(ctx context.Context, w http.Respon
|
||||
session := req.Session()
|
||||
module := req.Mod1()
|
||||
module2 := req.Mod2()
|
||||
query := req.Query()
|
||||
body := req.Body()
|
||||
|
||||
jmod, e := modulebase.GetJointModule2(session, module, module2)
|
||||
var obj jsonutils.JSONObject
|
||||
if e == nil { // update joint
|
||||
obj, e = jmod.Update(session, req.ResID(), req.ResID2(), nil, body)
|
||||
obj, e = jmod.Update(session, req.ResID(), req.ResID2(), query, body)
|
||||
} else { // update in context
|
||||
obj, e = module2.PutInContext(session, req.ResID2(), body, module, req.ResID())
|
||||
}
|
||||
@@ -669,12 +670,13 @@ func (f *ResourceHandlers) patchJointHandler(ctx context.Context, w http.Respons
|
||||
session := req.Session()
|
||||
module := req.Mod1()
|
||||
module2 := req.Mod2()
|
||||
query := req.Query()
|
||||
body := req.Body()
|
||||
|
||||
jmod, e := modulebase.GetJointModule2(session, module, module2)
|
||||
var obj jsonutils.JSONObject
|
||||
if e == nil { // update joint
|
||||
obj, e = jmod.Patch(session, req.ResID(), req.ResID2(), nil, body)
|
||||
obj, e = jmod.Patch(session, req.ResID(), req.ResID2(), query, body)
|
||||
} else { // update in context
|
||||
obj, e = module2.PatchInContext(session, req.ResID2(), body, module, req.ResID())
|
||||
}
|
||||
|
||||
@@ -2564,6 +2564,29 @@ func (self *SGuest) PerformDetachnetwork(
|
||||
return nil, httperrors.NewMissingParameterError("net_id")
|
||||
}
|
||||
|
||||
removeNics := make(map[string]*SGuestnetwork)
|
||||
for i := range gns {
|
||||
removeNics[gns[i].MacAddr] = &gns[i]
|
||||
}
|
||||
|
||||
slaveNics, err := self.GetSlaveNetworks()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetSlaveNetworks")
|
||||
}
|
||||
|
||||
for i := range slaveNics {
|
||||
teamMac := slaveNics[i].TeamWith
|
||||
if len(teamMac) > 0 {
|
||||
if _, ok := removeNics[teamMac]; ok {
|
||||
// to remove slave's master NIC, should also remove slave itself
|
||||
if _, ok2 := removeNics[slaveNics[i].MacAddr]; !ok2 {
|
||||
// otherwise, report the error
|
||||
return nil, errors.Wrap(errors.ErrInvalidStatus, "")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
err = self.detachNetworks(ctx, userCred, gns, input.Reserve)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "detachNetworks")
|
||||
@@ -2599,6 +2622,9 @@ func (guest *SGuest) fixDefaultGateway(ctx context.Context, userCred mcclient.To
|
||||
nicList := netutils2.SNicInfoList{}
|
||||
nics, _ := guest.GetNetworks("")
|
||||
for i := range nics {
|
||||
if nics[i].Virtual || len(nics[i].TeamWith) > 0 {
|
||||
continue
|
||||
}
|
||||
net, _ := nics[i].GetNetwork()
|
||||
if net != nil {
|
||||
nicList = nicList.Add(nics[i].IpAddr, nics[i].MacAddr, net.GuestGateway)
|
||||
|
||||
@@ -812,6 +812,9 @@ func (gn *SGuestnetwork) ValidateUpdateData(
|
||||
}
|
||||
}
|
||||
if input.IsDefault != nil && *input.IsDefault {
|
||||
if gn.Virtual || len(gn.TeamWith) > 0 {
|
||||
return input, errors.Wrap(httperrors.ErrInvalidStatus, "cannot set virtual/slave interface as default")
|
||||
}
|
||||
net, err := gn.GetNetwork()
|
||||
if err != nil {
|
||||
return input, errors.Wrapf(err, "GetNetwork")
|
||||
|
||||
@@ -1073,6 +1073,16 @@ func (guest *SGuest) GetNetworks(netId string) ([]SGuestnetwork, error) {
|
||||
return guestnics, nil
|
||||
}
|
||||
|
||||
func (guest *SGuest) GetSlaveNetworks() ([]SGuestnetwork, error) {
|
||||
guestnics := make([]SGuestnetwork, 0)
|
||||
q := guest.GetNetworksQuery("").IsNotEmpty("team_with")
|
||||
err := db.FetchModelObjects(GuestnetworkManager, q, &guestnics)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
return guestnics, nil
|
||||
}
|
||||
|
||||
func (guest *SGuest) ConvertEsxiNetworks(targetGuest *SGuest) error {
|
||||
gns, err := guest.GetNetworks("")
|
||||
if err != nil {
|
||||
|
||||
@@ -841,7 +841,7 @@ func (d *sDebianLikeRootFs) PrepareFsForTemplate(rootFs IDiskPartition) error {
|
||||
netplanDir := "/etc/netplan/"
|
||||
if rootFs.Exists(netplanDir, false) {
|
||||
for _, f := range rootFs.ListDir(netplanDir, false) {
|
||||
rootFs.Remove(netplanDir+f, false)
|
||||
rootFs.Remove(filepath.Join(netplanDir, f), false)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
@@ -885,16 +885,6 @@ func getNicTeamingConfigCmds(slaves []*types.SServerNic) string {
|
||||
return cmds.String()
|
||||
}
|
||||
|
||||
func (d *sDebianLikeRootFs) deployNetplanConfigFile(rootFs IDiskPartition, nics []*types.SServerNic) error {
|
||||
netplanDir := "/etc/netplan/"
|
||||
dirExists := rootFs.Exists(netplanDir, false)
|
||||
if !dirExists {
|
||||
return nil
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics []*types.SServerNic) error {
|
||||
if err := d.sLinuxRootFs.DeployNetworkingScripts(rootFs, nics); err != nil {
|
||||
return err
|
||||
@@ -914,24 +904,24 @@ func (d *sDebianLikeRootFs) DeployNetworkingScripts(rootFs IDiskPartition, nics
|
||||
// ToServerNics(nics)
|
||||
allNics, bondNics := convertNicConfigs(nics)
|
||||
|
||||
netplanDir := "/etc/netplan"
|
||||
if rootFs.Exists(netplanDir, false) {
|
||||
for _, f := range rootFs.ListDir(netplanDir, false) {
|
||||
rootFs.Remove(netplanDir+f, false)
|
||||
}
|
||||
netplanConfig := NewNetplanConfig(allNics, bondNics)
|
||||
log.Debugf("netplanConfig:\n %s", netplanConfig.YAMLString())
|
||||
if err := rootFs.FilePutContents(path.Join(netplanDir, "config.yaml"), netplanConfig.YAMLString(), false, false); err != nil {
|
||||
return errors.Wrap(err, "Put netplan config")
|
||||
}
|
||||
}
|
||||
|
||||
mainNic := getMainNic(allNics)
|
||||
var mainIp string
|
||||
if mainNic != nil {
|
||||
mainIp = mainNic.Ip
|
||||
}
|
||||
|
||||
netplanDir := "/etc/netplan"
|
||||
if rootFs.Exists(netplanDir, false) {
|
||||
for _, f := range rootFs.ListDir(netplanDir, false) {
|
||||
rootFs.Remove(filepath.Join(netplanDir, f), false)
|
||||
}
|
||||
netplanConfig := NewNetplanConfig(allNics, bondNics, mainIp)
|
||||
log.Debugf("netplanConfig:\n %s", netplanConfig.YAMLString())
|
||||
if err := rootFs.FilePutContents(path.Join(netplanDir, "config.yaml"), netplanConfig.YAMLString(), false, false); err != nil {
|
||||
return errors.Wrap(err, "Put netplan config")
|
||||
}
|
||||
}
|
||||
|
||||
var systemdResolveConfig strings.Builder
|
||||
dnss := []string{}
|
||||
domains := []string{}
|
||||
|
||||
@@ -24,16 +24,16 @@ import (
|
||||
"yunion.io/x/onecloud/pkg/util/netutils2"
|
||||
)
|
||||
|
||||
func NewNetplanConfig(allNics []*types.SServerNic, bondNics []*types.SServerNic) *netplan.Configuration {
|
||||
network := newNetplanNetwork(allNics, bondNics)
|
||||
func NewNetplanConfig(allNics []*types.SServerNic, bondNics []*types.SServerNic, mainIp string) *netplan.Configuration {
|
||||
network := newNetplanNetwork(allNics, bondNics, mainIp)
|
||||
return netplan.NewConfiguration(network)
|
||||
}
|
||||
|
||||
func newNetplanNetwork(allNics []*types.SServerNic, bondNics []*types.SServerNic) *netplan.Network {
|
||||
func newNetplanNetwork(allNics []*types.SServerNic, bondNics []*types.SServerNic, mainIp string) *netplan.Network {
|
||||
network := netplan.NewNetwork()
|
||||
|
||||
for _, nic := range allNics {
|
||||
nicConf := getNetplanEthernetConfig(nic, false)
|
||||
nicConf := getNetplanEthernetConfig(nic, false, mainIp)
|
||||
|
||||
if nicConf == nil {
|
||||
continue
|
||||
@@ -69,7 +69,7 @@ func newNetplanNetwork(allNics []*types.SServerNic, bondNics []*types.SServerNic
|
||||
network.AddEthernet(sn.Name, nicConf)
|
||||
}
|
||||
|
||||
netConf := getNetplanEthernetConfig(bondNic, true)
|
||||
netConf := getNetplanEthernetConfig(bondNic, true, mainIp)
|
||||
|
||||
if netConf.Mtu == 0 {
|
||||
netConf.Mtu = defaultMtu
|
||||
@@ -84,7 +84,7 @@ func newNetplanNetwork(allNics []*types.SServerNic, bondNics []*types.SServerNic
|
||||
return network
|
||||
}
|
||||
|
||||
func getNetplanEthernetConfig(nic *types.SServerNic, isBond bool) *netplan.EthernetConfig {
|
||||
func getNetplanEthernetConfig(nic *types.SServerNic, isBond bool, mainIp string) *netplan.EthernetConfig {
|
||||
var nicConf *netplan.EthernetConfig
|
||||
|
||||
if !isBond && (nic.TeamingMaster != nil || nic.TeamingSlaves != nil) {
|
||||
@@ -94,12 +94,17 @@ func getNetplanEthernetConfig(nic *types.SServerNic, isBond bool) *netplan.Ether
|
||||
nicConf = netplan.NewStaticEthernetConfig(addr, "", "", "", nil, nil, nil)
|
||||
} else if nic.Manual {
|
||||
addr := fmt.Sprintf("%s/%d", nic.Ip, nic.Masklen)
|
||||
gateway := nic.Gateway
|
||||
gateway := ""
|
||||
if nic.Ip == mainIp && len(mainIp) > 0 {
|
||||
gateway = nic.Gateway
|
||||
}
|
||||
addr6 := ""
|
||||
gateway6 := ""
|
||||
if len(nic.Ip6) > 0 {
|
||||
addr6 = fmt.Sprintf("%s/%d", nic.Ip6, nic.Masklen6)
|
||||
gateway6 = nic.Gateway6
|
||||
if nic.Ip == mainIp && len(mainIp) > 0 {
|
||||
gateway6 = nic.Gateway6
|
||||
}
|
||||
}
|
||||
|
||||
var routes []*netplan.Route
|
||||
|
||||
@@ -25,10 +25,12 @@ import (
|
||||
|
||||
func TestNewNetplanConfig(t *testing.T) {
|
||||
cases := []struct {
|
||||
nics []*types.SServerNic
|
||||
want *netplan.Configuration
|
||||
mainIp string
|
||||
nics []*types.SServerNic
|
||||
want *netplan.Configuration
|
||||
}{
|
||||
{
|
||||
mainIp: "10.168.222.175",
|
||||
nics: []*types.SServerNic{
|
||||
&types.SServerNic{
|
||||
Name: "eth0",
|
||||
@@ -137,10 +139,119 @@ func TestNewNetplanConfig(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
mainIp: "10.168.22.175",
|
||||
nics: []*types.SServerNic{
|
||||
&types.SServerNic{
|
||||
Name: "eth0",
|
||||
Index: 0,
|
||||
Bridge: "br0",
|
||||
Domain: "cloud.local",
|
||||
Ip: "10.168.222.175",
|
||||
Vlan: 1,
|
||||
Driver: "virtio",
|
||||
Masklen: 24,
|
||||
Virtual: false,
|
||||
Manual: true,
|
||||
WireId: "399a06f3-7925-46c1-8b9f-d5a8580a74df",
|
||||
NetId: "22c93412-5882-4de0-8357-45ce647ceada",
|
||||
Mac: "00:24:c7:16:80:f2",
|
||||
BandWidth: 1000,
|
||||
Mtu: 1500,
|
||||
Dns: "8.8.8.8",
|
||||
Ntp: "",
|
||||
Net: "vnet222",
|
||||
Interface: "ens5",
|
||||
Gateway: "10.168.222.1",
|
||||
Ifname: "vnet222-175",
|
||||
Routes: nil,
|
||||
|
||||
LinkUp: true,
|
||||
},
|
||||
&types.SServerNic{
|
||||
Name: "eth1",
|
||||
Index: 1,
|
||||
Bridge: "br0",
|
||||
Domain: "cloud.local",
|
||||
Ip: "",
|
||||
Vlan: 1,
|
||||
Driver: "virtio",
|
||||
Masklen: 0,
|
||||
Virtual: true,
|
||||
Manual: true,
|
||||
WireId: "399a06f3-7925-46c1-8b9f-d5a8580a74df",
|
||||
NetId: "22c93412-5882-4de0-8357-45ce647ceada",
|
||||
Mac: "00:24:c7:16:80:f3",
|
||||
BandWidth: 1000,
|
||||
Mtu: 1500,
|
||||
Dns: "8.8.8.8",
|
||||
Ntp: "",
|
||||
Net: "vnet222",
|
||||
Interface: "ens5",
|
||||
Gateway: "",
|
||||
Ifname: "vnet222-bpg",
|
||||
Routes: nil,
|
||||
|
||||
LinkUp: true,
|
||||
TeamWith: "00:24:c7:16:80:f2",
|
||||
},
|
||||
},
|
||||
want: &netplan.Configuration{
|
||||
Network: &netplan.Network{
|
||||
Version: 2,
|
||||
Renderer: netplan.NetworkRendererNetworkd,
|
||||
Ethernets: map[string]*netplan.EthernetConfig{
|
||||
"eth0": &netplan.EthernetConfig{
|
||||
MacAddress: "00:24:c7:16:80:f2",
|
||||
Match: &netplan.EthernetConfigMatch{
|
||||
MacAddress: "00:24:c7:16:80:f2",
|
||||
},
|
||||
Mtu: 1500,
|
||||
},
|
||||
"eth1": &netplan.EthernetConfig{
|
||||
MacAddress: "00:24:c7:16:80:f3",
|
||||
Match: &netplan.EthernetConfigMatch{
|
||||
MacAddress: "00:24:c7:16:80:f3",
|
||||
},
|
||||
Mtu: 1500,
|
||||
},
|
||||
},
|
||||
Bonds: map[string]*netplan.Bond{
|
||||
"bond0": &netplan.Bond{
|
||||
EthernetConfig: netplan.EthernetConfig{
|
||||
Addresses: []string{
|
||||
"10.168.222.175/24",
|
||||
},
|
||||
MacAddress: "00:24:c7:16:80:f2",
|
||||
Nameservers: &netplan.Nameservers{
|
||||
Search: []string{
|
||||
"cloud.local",
|
||||
},
|
||||
Addresses: []string{
|
||||
"8.8.8.8",
|
||||
},
|
||||
},
|
||||
Mtu: 1500,
|
||||
},
|
||||
Interfaces: []string{
|
||||
"eth0",
|
||||
"eth1",
|
||||
},
|
||||
Parameters: &netplan.BondMode4Params{
|
||||
BondModeBaseParams: &netplan.BondModeBaseParams{
|
||||
Mode: "802.3ad",
|
||||
MiiMonitorInterval: 100,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
allNics, bondNics := convertNicConfigs(c.nics)
|
||||
netplanConfig := NewNetplanConfig(allNics, bondNics)
|
||||
netplanConfig := NewNetplanConfig(allNics, bondNics, c.mainIp)
|
||||
if jsonutils.Marshal(netplanConfig).String() != jsonutils.Marshal(c.want).String() {
|
||||
t.Errorf("nics: %s want: %s got: %s", jsonutils.Marshal(c.nics), jsonutils.Marshal(c.want).PrettyString(), jsonutils.Marshal(netplanConfig).PrettyString())
|
||||
}
|
||||
|
||||
@@ -121,6 +121,7 @@ func convertNicConfigs(nics []*types.SServerNic) ([]*types.SServerNic, []*types.
|
||||
nnic.Ip6 = ""
|
||||
nnic.Masklen6 = 0
|
||||
nnic.Gateway6 = ""
|
||||
nnic.IsDefault = false
|
||||
tnic.Name = fmt.Sprintf("%s%d", netDevPrefix, tnic.Index)
|
||||
tnic.TeamingMaster = master
|
||||
tnic.Ip = ""
|
||||
@@ -129,6 +130,7 @@ func convertNicConfigs(nics []*types.SServerNic) ([]*types.SServerNic, []*types.
|
||||
tnic.Ip6 = ""
|
||||
tnic.Masklen6 = 0
|
||||
tnic.Gateway6 = ""
|
||||
tnic.IsDefault = false
|
||||
master.Name = fmt.Sprintf("bond%d", len(bondNics))
|
||||
master.TeamingSlaves = []*types.SServerNic{&nnic, &tnic}
|
||||
// why reset master.Mac?
|
||||
|
||||
Reference in New Issue
Block a user