mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-24 16:03:43 +08:00
Merge pull request #1689 from wanyaoqi/feature/wyq/auto-create-subnet
feature: auto create subnet on host register
This commit is contained in:
@@ -1834,6 +1834,117 @@ func (self *SNetwork) PerformSplit(ctx context.Context, userCred mcclient.TokenC
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) AllowPerformTryCreateNetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return db.IsAdminAllowClassPerform(userCred, manager, "try-create-network")
|
||||
}
|
||||
|
||||
func (manager *SNetworkManager) PerformTryCreateNetwork(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
ip, err := data.GetString("ip")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("ip")
|
||||
}
|
||||
ipV4, err := netutils.NewIPV4Addr(ip)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("ip")
|
||||
}
|
||||
mask, err := data.Int("mask")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("mask")
|
||||
}
|
||||
serverType, err := data.GetString("server_type")
|
||||
if err != nil {
|
||||
return nil, httperrors.NewMissingParameterError("server_type")
|
||||
}
|
||||
if serverType != api.NETWORK_TYPE_BAREMETAL {
|
||||
return nil, httperrors.NewBadRequestError("Only support server type %s", api.NETWORK_TYPE_BAREMETAL)
|
||||
}
|
||||
if !jsonutils.QueryBoolean(data, "is_on_premise", false) {
|
||||
return nil, httperrors.NewBadRequestError("Only support on premise network")
|
||||
}
|
||||
|
||||
var (
|
||||
ipV4NetAddr = ipV4.NetAddr(int8(mask))
|
||||
nm *SNetwork
|
||||
matched bool
|
||||
)
|
||||
|
||||
q := NetworkManager.Query().Equals("server_type", serverType).Equals("guest_ip_mask", mask)
|
||||
q = managedResourceFilterByCloudType(q, query, "wire_id", func() *sqlchemy.SQuery {
|
||||
wires := WireManager.Query().SubQuery()
|
||||
vpcs := VpcManager.Query().SubQuery()
|
||||
subq := wires.Query(wires.Field("id"))
|
||||
subq = subq.Join(vpcs, sqlchemy.Equals(vpcs.Field("id"), wires.Field("vpc_id")))
|
||||
return subq
|
||||
})
|
||||
|
||||
rows, err := q.Rows()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
for rows.Next() {
|
||||
item, err := db.NewModelObject(NetworkManager)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = q.Row2Struct(rows, item)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
n := item.(*SNetwork)
|
||||
if n.GetIPRange().Contains(ipV4) {
|
||||
nm = n
|
||||
matched = true
|
||||
break
|
||||
} else if nIpV4, _ := netutils.NewIPV4Addr(n.GuestIpStart); nIpV4.NetAddr(n.GuestIpMask) == ipV4NetAddr {
|
||||
nm = n
|
||||
matched = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
ret := jsonutils.NewDict()
|
||||
if nm == nil {
|
||||
ret.Set("find_matched", jsonutils.JSONFalse)
|
||||
return ret, nil
|
||||
} else {
|
||||
ret.Set("find_matched", jsonutils.JSONTrue)
|
||||
ret.Set("wire_id", jsonutils.NewString(nm.WireId))
|
||||
}
|
||||
if !matched {
|
||||
log.Infof("Find same subnet network %s %s/%d", nm.Name, nm.GuestGateway, nm.GuestIpMask)
|
||||
newNetwork := new(SNetwork)
|
||||
newNetwork.SetModelManager(NetworkManager, newNetwork)
|
||||
newNetwork.GuestIpStart = ip
|
||||
newNetwork.GuestIpEnd = ip
|
||||
newNetwork.GuestGateway = nm.GuestGateway
|
||||
newNetwork.GuestIpMask = int8(mask)
|
||||
newNetwork.GuestDns = nm.GuestDns
|
||||
newNetwork.GuestDhcp = nm.GuestDhcp
|
||||
newNetwork.WireId = nm.WireId
|
||||
newNetwork.ServerType = serverType
|
||||
newNetwork.IsPublic = nm.IsPublic
|
||||
newNetwork.ProjectId = userCred.GetProjectId()
|
||||
newNetwork.DomainId = userCred.GetProjectDomainId()
|
||||
newName, err := db.GenerateName(NetworkManager, userCred, fmt.Sprintf("%s#", nm.Name))
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInternalServerError("GenerateName fail %s", err)
|
||||
}
|
||||
newNetwork.Name = newName
|
||||
|
||||
err = NetworkManager.TableSpec().Insert(newNetwork)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
err = newNetwork.CustomizeCreate(ctx, userCred, userCred, query, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
newNetwork.PostCreate(ctx, userCred, userCred, query, data)
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (network *SNetwork) getAllocTimoutDuration() time.Duration {
|
||||
tos := network.AllocTimoutSeconds
|
||||
if tos < options.Options.MinimalIpAddrReusedIntervalSeconds {
|
||||
|
||||
@@ -499,6 +499,19 @@ func (h *SHostInfo) detectiveOvsVersion() {
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostInfo) GetMasterNicIpAndMask() (string, int) {
|
||||
if h.MasterNic != nil {
|
||||
mask, _ := h.MasterNic.Mask.Size()
|
||||
return h.MasterNic.Addr, mask
|
||||
}
|
||||
for _, n := range h.Nics {
|
||||
if len(n.Ip) > 0 {
|
||||
return n.Ip, n.Mask
|
||||
}
|
||||
}
|
||||
return "", 0
|
||||
}
|
||||
|
||||
func (h *SHostInfo) GetMasterIp() string {
|
||||
if h.MasterNic != nil {
|
||||
return h.MasterNic.Addr
|
||||
@@ -562,27 +575,76 @@ func (h *SHostInfo) onFail() {
|
||||
panic("register failed, try 30 seconds later...")
|
||||
}
|
||||
|
||||
// try to create network on region.
|
||||
func (h *SHostInfo) tryCreateNetworkOnWire() {
|
||||
masterIp, mask := h.GetMasterNicIpAndMask()
|
||||
log.Debugf("Get master ip %s and mask %d", masterIp, mask)
|
||||
if len(masterIp) == 0 || mask == 0 {
|
||||
return
|
||||
}
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("ip", jsonutils.NewString(masterIp))
|
||||
params.Set("mask", jsonutils.NewInt(int64(mask)))
|
||||
params.Set("is_on_premise", jsonutils.JSONTrue)
|
||||
params.Set("server_type", jsonutils.NewString(api.NETWORK_TYPE_BAREMETAL))
|
||||
ret, err := modules.Networks.PerformClassAction(
|
||||
hostutils.GetComputeSession(context.Background()),
|
||||
"try-create-network", params)
|
||||
if err != nil {
|
||||
log.Errorf("try create network get error %s", err)
|
||||
h.onFail()
|
||||
}
|
||||
if !jsonutils.QueryBoolean(ret, "find_matched", false) {
|
||||
log.Errorf("Fail to get network info: no networks")
|
||||
h.onFail()
|
||||
}
|
||||
wireId, err := ret.GetString("wire_id")
|
||||
if err != nil {
|
||||
log.Errorf("Fail to get network info: no wire id")
|
||||
h.onFail()
|
||||
}
|
||||
h.onGetWireId(wireId)
|
||||
}
|
||||
|
||||
func (h *SHostInfo) fetchAccessNetworkInfo() {
|
||||
masterIp := h.GetMasterIp()
|
||||
if len(masterIp) == 0 {
|
||||
panic("master ip not found")
|
||||
}
|
||||
log.Debugf("Master ip %s to fetch wire", masterIp)
|
||||
params := jsonutils.NewDict()
|
||||
params.Set("ip", jsonutils.NewString(masterIp))
|
||||
params.Set("is_on_premise", jsonutils.JSONTrue)
|
||||
params.Set("limit", jsonutils.NewInt(0))
|
||||
wire, err := hostutils.GetWireOfIp(context.Background(), params)
|
||||
|
||||
res, err := modules.Networks.List(h.GetSession(), params)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
h.onFail()
|
||||
}
|
||||
if len(res.Data) == 0 {
|
||||
h.tryCreateNetworkOnWire()
|
||||
} else if len(res.Data) == 1 {
|
||||
wireId, _ := res.Data[0].GetString("wire_id")
|
||||
h.onGetWireId(wireId)
|
||||
} else {
|
||||
log.Errorf("Fail to get network info: no networks")
|
||||
h.onFail()
|
||||
}
|
||||
}
|
||||
|
||||
func (h *SHostInfo) onGetWireId(wireId string) {
|
||||
wire, err := hostutils.GetWireInfo(context.Background(), wireId)
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
h.onFail()
|
||||
}
|
||||
h.ZoneId, err = wire.GetString("zone_id")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
h.onFail()
|
||||
} else {
|
||||
h.ZoneId, err = wire.GetString("zone_id")
|
||||
if err != nil {
|
||||
log.Errorln(err)
|
||||
h.onFail()
|
||||
} else {
|
||||
h.getZoneInfo(h.ZoneId, false)
|
||||
}
|
||||
h.getZoneInfo(h.ZoneId, false)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -591,6 +653,7 @@ func (h *SHostInfo) GetSession() *mcclient.ClientSession {
|
||||
}
|
||||
|
||||
func (h *SHostInfo) getZoneInfo(zoneId string, standalone bool) {
|
||||
log.Debugf("Start GetZoneInfo %s %v", zoneId, standalone)
|
||||
var params = jsonutils.NewDict()
|
||||
params.Set("standalone", jsonutils.NewBool(standalone))
|
||||
res, err := modules.Zones.Get(h.GetSession(),
|
||||
|
||||
@@ -188,6 +188,7 @@ type SNIC struct {
|
||||
Ip string
|
||||
Network string
|
||||
WireId string
|
||||
Mask int
|
||||
|
||||
Bandwidth int
|
||||
BridgeDev hostbridge.IBridgeDriver
|
||||
@@ -250,6 +251,10 @@ func NewNIC(desc string) (*SNIC, error) {
|
||||
for wait < max {
|
||||
inf := netutils2.NewNetInterface(nic.Inter)
|
||||
if inf.Addr == nic.Ip {
|
||||
mask, _ := inf.Mask.Size()
|
||||
if mask > 0 {
|
||||
nic.Mask = mask
|
||||
}
|
||||
break
|
||||
}
|
||||
br := netutils2.NewNetInterface(nic.Bridge)
|
||||
|
||||
Reference in New Issue
Block a user