networks: 添加ifname_hint字段

- 升级部署时,从network.Name初始化
 - 创建时,尝试从network.Name取值,取不到则生成随机值
 - 不允许更新
This commit is contained in:
Yousong Zhou
2019-08-22 08:02:50 +00:00
parent ce0ca65c2b
commit 5bf89ae89b
3 changed files with 72 additions and 5 deletions
+4
View File
@@ -210,6 +210,7 @@ func init() {
NETMASK int64 `help:"Length of network mask"`
Gateway string `help:"Default gateway"`
VlanId int64 `help:"Vlan ID" default:"1"`
IfnameHint string `help:"Hint for ifname generation"`
AllocPolicy string `help:"Address allocation policy" choices:"none|stepdown|stepup|random"`
ServerType string `help:"Server type" choices:"baremetal|guest|container|pxe|ipmi"`
Desc string `help:"Description" metavar:"DESCRIPTION"`
@@ -229,6 +230,9 @@ func init() {
if len(args.ServerType) > 0 {
params.Add(jsonutils.NewString(args.ServerType), "server_type")
}
if len(args.IfnameHint) > 0 {
params.Add(jsonutils.NewString(args.IfnameHint), "ifname_hint")
}
if len(args.AllocPolicy) > 0 {
params.Add(jsonutils.NewString(args.AllocPolicy), "alloc_policy")
}
+1 -1
View File
@@ -224,7 +224,7 @@ func (self *SGuestnetwork) getVirtualRand(width int, randomized bool) string {
func (self *SGuestnetwork) generateIfname(network *SNetwork, virtual bool, randomized bool) string {
pattern := regexp.MustCompile(`\W+`)
nName := pattern.ReplaceAllString(network.Name, "")
nName := pattern.ReplaceAllString(network.IfnameHint, "")
if len(nName) > MAX_IFNAME_SIZE-4 {
nName = nName[:(MAX_IFNAME_SIZE - 4)]
}
+67 -4
View File
@@ -44,6 +44,7 @@ import (
"yunion.io/x/onecloud/pkg/mcclient"
"yunion.io/x/onecloud/pkg/mcclient/auth"
"yunion.io/x/onecloud/pkg/util/logclient"
"yunion.io/x/onecloud/pkg/util/rand"
"yunion.io/x/onecloud/pkg/util/rbacutils"
)
@@ -76,8 +77,6 @@ func init() {
"networks",
),
}
NetworkManager.NameLength = 9
NetworkManager.NameRequireAscii = true
NetworkManager.SetVirtualObject(NetworkManager)
}
@@ -85,6 +84,8 @@ type SNetwork struct {
db.SSharableVirtualResourceBase
db.SExternalizedResourceBase
IfnameHint string `width:"9" charset:"ascii" nullable:"false" list:"user" create:"optional"`
GuestIpStart string `width:"16" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"` // Column(VARCHAR(16, charset='ascii'), nullable=False)
GuestIpEnd string `width:"16" charset:"ascii" nullable:"false" list:"user" update:"user" create:"required"` // Column(VARCHAR(16, charset='ascii'), nullable=False)
GuestIpMask int8 `nullable:"false" list:"user" update:"user" create:"required"` // Column(TINYINT, nullable=False)
@@ -1104,6 +1105,39 @@ func isValidMaskLen(maskLen int64) bool {
}
}
func (manager *SNetworkManager) newIfnameHint(hint string) (string, error) {
r := ""
// sanitize hint
for _, c := range hint {
if (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '-' || c == '_' {
r += string(c)
}
}
newHint := func() (string, error) {
for i := 0; i < 3; i++ {
r := rand.String(7)
cnt, err := manager.Query().Equals("ifname_hint", r).CountWithError()
if err == nil && cnt == 0 {
return r, nil
}
}
return "", fmt.Errorf("failed finding ifname hint after 3 tries")
}
if len(r) < 3 {
return newHint()
}
if len(r) > 9 {
r = r[:9]
}
if cnt, err := manager.Query().Equals("ifname_hint", r).CountWithError(); err != nil {
return "", err
} else if cnt > 0 {
r, err := newHint()
return r, err
}
return r, nil
}
func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
prefixStr, _ := data.GetString("guest_ip_prefix")
var maskLen64 int64
@@ -1143,6 +1177,18 @@ func (manager *SNetworkManager) ValidateCreateData(ctx context.Context, userCred
data.Add(jsonutils.NewString(startIp.String()), "guest_ip_start")
data.Add(jsonutils.NewString(endIp.String()), "guest_ip_end")
{
hint, _ := data.GetString("ifname_hint")
if hint == "" {
hint, _ = data.GetString("name")
}
hint, err = manager.newIfnameHint(hint)
if err != nil {
return nil, httperrors.NewBadRequestError("cannot derive valid ifname hint: %v", err)
}
data.Set("ifname_hint", jsonutils.NewString(hint))
}
for _, key := range []string{"guest_gateway", "guest_dns", "guest_dhcp"} {
ipStr, _ := data.GetString(key)
if len(ipStr) > 0 && !regutils.MatchIPAddr(ipStr) {
@@ -1700,9 +1746,26 @@ func (manager *SNetworkManager) InitializeData() error {
return err
}
for _, n := range networks {
if len(n.ExternalId) == 0 && len(n.WireId) > 0 && n.Status == api.NETWORK_STATUS_INIT {
if n.ExternalId != "" {
var statusNew string
if n.WireId != "" && n.Status == api.NETWORK_STATUS_INIT {
statusNew = api.NETWORK_STATUS_AVAILABLE
}
db.Update(&n, func() error {
n.Status = api.NETWORK_STATUS_AVAILABLE
if statusNew != "" {
n.Status = statusNew
}
return nil
})
} else {
var ifnameHintNew string
if n.IfnameHint == "" {
ifnameHintNew = n.Name
}
db.Update(&n, func() error {
if ifnameHintNew != "" {
n.IfnameHint = ifnameHintNew
}
return nil
})
}