mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-09-01 15:07:17 +08:00
feat(region,host,vpcagent): allow guest network dedicate secgroups (#24263)
This commit is contained in:
@@ -36,4 +36,7 @@ func init() {
|
||||
cmd.Perform("change-owner", &options.SecgroupChangeOwnerOptions{})
|
||||
cmd.Perform("import-rules", &options.SecgroupImportRulesOptions{})
|
||||
cmd.PerformClass("clean", &options.SecgroupCleanOptions{})
|
||||
|
||||
scmd := shell.NewResourceCmd(&modules.Servernetworksecgroups)
|
||||
scmd.List(&options.ServerNetworkSecgroupListOptions{})
|
||||
}
|
||||
|
||||
@@ -153,6 +153,9 @@ func init() {
|
||||
cmd.Get("numa-info", new(options.ServerIdOptions))
|
||||
cmd.BatchPerform("screen-dump", new(options.ServerIdsOptions))
|
||||
cmd.Perform("set-network-num-queues", new(options.ServerSetNetworkNumQueues))
|
||||
cmd.Perform("set-network-secgroup", new(options.ServerNetworkSecGroupsOptions))
|
||||
cmd.Perform("add-network-secgroup", new(options.ServerNetworkSecGroupsOptions))
|
||||
cmd.Perform("revoke-network-secgroup", new(options.ServerNetworkSecGroupsOptions))
|
||||
|
||||
cmd.GetProperty(&options.ServerStatusStatisticsOptions{})
|
||||
cmd.GetProperty(&options.ServerProjectStatisticsOptions{})
|
||||
|
||||
@@ -130,6 +130,9 @@ type NetworkConfig struct {
|
||||
Domain string `json:"domain_id"`
|
||||
Ifname string `json:"ifname"`
|
||||
Schedtags []*SchedtagConfig `json:"schedtags"`
|
||||
|
||||
// network secgroups
|
||||
Secgroups []string `json:"secgroups"`
|
||||
}
|
||||
|
||||
type AttachNetworkInput struct {
|
||||
|
||||
@@ -20,6 +20,8 @@ import (
|
||||
"yunion.io/x/cloudmux/pkg/apis/compute"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/pkg/gotypes"
|
||||
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
)
|
||||
|
||||
type GuestnetworkDetails struct {
|
||||
@@ -82,6 +84,12 @@ type GuestnetworkShortDesc struct {
|
||||
Index int `json:"index"`
|
||||
}
|
||||
|
||||
type GuestnetworkSecgroupShortDesc struct {
|
||||
NetworkIndex int `json:"network_index"`
|
||||
Secgroups []apis.StandaloneShortDesc `json:"secgroups"`
|
||||
Mac string `json:"mac"`
|
||||
}
|
||||
|
||||
type GuestnetworkListInput struct {
|
||||
GuestJointsListInput
|
||||
|
||||
@@ -148,6 +156,9 @@ type GuestnetworkBaseDesc struct {
|
||||
WireId string `json:"wire_id"`
|
||||
Interface string `json:"interface"`
|
||||
|
||||
Secgroups []*SecgroupJsonDesc `json:"secgroups"`
|
||||
SecurityRules string `json:"security_rules"`
|
||||
|
||||
Vpc struct {
|
||||
Id string `json:"id"`
|
||||
Provider string `json:"provider"`
|
||||
@@ -183,6 +194,14 @@ type GuestnetworkJsonDesc struct {
|
||||
LinkUp bool `json:"link_up"`
|
||||
}
|
||||
|
||||
type GuestnetworkSecgroupDesc struct {
|
||||
Secgroups []*SecgroupJsonDesc `json:"secgroups"`
|
||||
SecurityRules string `json:"security_rules"`
|
||||
|
||||
Index int `json:"index"`
|
||||
Mac string `json:"mac"`
|
||||
}
|
||||
|
||||
type SNicTrafficRecord struct {
|
||||
RxTraffic int64 `json:"rx_traffic"`
|
||||
TxTraffic int64 `json:"tx_traffic"`
|
||||
|
||||
@@ -258,6 +258,9 @@ type ServerDetails struct {
|
||||
// 关联主安全组
|
||||
Secgroup string `json:"secgroup"`
|
||||
|
||||
// 网卡级别安全组
|
||||
NetworkSecgroups []GuestnetworkSecgroupShortDesc `json:"network_secgroups"`
|
||||
|
||||
// 浮动IP
|
||||
Eip string `json:"eip"`
|
||||
// 浮动IP类型
|
||||
@@ -573,12 +576,32 @@ type GuestSetSecgroupInput struct {
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
}
|
||||
|
||||
type GuestSetNetworkSecgroupInput struct {
|
||||
// 安全组Id列表
|
||||
// 实例必须处于运行,休眠或者关机状态
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
|
||||
// 虚机网卡 index 或者 mac 地址
|
||||
NetworkIndex *int `json:"network_index"`
|
||||
MacAddr string `json:"mac_addr"`
|
||||
}
|
||||
|
||||
type GuestRevokeSecgroupInput struct {
|
||||
// 安全组Id列表
|
||||
// 实例必须处于运行,休眠或者关机状态
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
}
|
||||
|
||||
type GuestRevokeNetworkSecgroupInput struct {
|
||||
// 安全组Id列表
|
||||
// 实例必须处于运行,休眠或者关机状态
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
|
||||
// 虚机网卡 index 或者 mac 地址
|
||||
NetworkIndex *int `json:"network_index"`
|
||||
MacAddr string `json:"mac_addr"`
|
||||
}
|
||||
|
||||
type GuestAssignSecgroupInput struct {
|
||||
// 安全组Id
|
||||
// 实例必须处于运行,休眠或者关机状态
|
||||
@@ -608,6 +631,12 @@ type GuestAddSecgroupInput struct {
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
}
|
||||
|
||||
type GuestNetworkAddSecgroupInput struct {
|
||||
SecgroupIds []string `json:"secgroup_ids"`
|
||||
|
||||
NetworkIndex *int `json:"network_index"`
|
||||
}
|
||||
|
||||
type ServerRemoteUpdateInput struct {
|
||||
// 是否覆盖替换所有标签
|
||||
ReplaceTags *bool `json:"replace_tags" help:"replace all remote tags"`
|
||||
@@ -944,9 +973,10 @@ type GuestJsonDesc struct {
|
||||
|
||||
NetworkRoles []string `json:"network_roles"`
|
||||
|
||||
Secgroups []*SecgroupJsonDesc `json:"secgroups"`
|
||||
SecurityRules string `json:"security_rules"`
|
||||
AdminSecurityRules string `json:"admin_security_rules"`
|
||||
Secgroups []*SecgroupJsonDesc `json:"secgroups"`
|
||||
SecurityRules string `json:"security_rules"`
|
||||
AdminSecurityRules string `json:"admin_security_rules"`
|
||||
NicSecgroups []*GuestnetworkSecgroupDesc `json:"nic_secgroups"`
|
||||
|
||||
ExtraOptions jsonutils.JSONObject `json:"extra_options"`
|
||||
|
||||
|
||||
@@ -272,6 +272,9 @@ type SecgroupDetails struct {
|
||||
// 关联云主机数量, 不包含回收站云主机
|
||||
GuestCnt int `json:"guest_cnt,allowempty"`
|
||||
|
||||
// 关联云主机网卡数量, 不包含回收站云主机
|
||||
GuestNicCnt int `json:"guest_nic_cnt,allowempty"`
|
||||
|
||||
// 关联此安全组的云主机is_system为true数量, , 不包含回收站云主机
|
||||
SystemGuestCnt int `json:"system_guest_cnt,allowempty"`
|
||||
|
||||
@@ -310,6 +313,16 @@ type GuestsecgroupListInput struct {
|
||||
SecgroupFilterListInput
|
||||
}
|
||||
|
||||
type GuestnetworksecgroupListInput struct {
|
||||
apis.ResourceBaseListInput
|
||||
ServerFilterListInput
|
||||
SecgroupFilterListInput
|
||||
|
||||
NetworkIndex *int `json:"network_index"`
|
||||
|
||||
IsAdmin bool `json:"is_admin"`
|
||||
}
|
||||
|
||||
type ElasticcachesecgroupListInput struct {
|
||||
ElasticcacheJointsListInput
|
||||
SecgroupFilterListInput
|
||||
@@ -324,6 +337,34 @@ type GuestsecgroupDetails struct {
|
||||
Secgroup string `json:"secgroup"`
|
||||
}
|
||||
|
||||
type GuestnetworksecgroupDetails struct {
|
||||
GuestResourceInfo
|
||||
|
||||
SGuestsecgroup
|
||||
|
||||
SecurityGroupResourceInfo
|
||||
|
||||
ProjectId string `json:"tenant_id"`
|
||||
|
||||
apis.ProjectizedResourceInfo
|
||||
|
||||
// 安全组状态
|
||||
SecgroupStatus string `json:"secgroup_status"`
|
||||
|
||||
// VPC ID
|
||||
VpcId string `json:"vpc_id"`
|
||||
Vpc string `json:"vpc"`
|
||||
|
||||
NetworkIndex int `json:"network_index"`
|
||||
GuestNetwork string `json:"guest_network"`
|
||||
MacAddr string `json:"mac_addr"`
|
||||
Ifname string `json:"ifname"`
|
||||
IpAddr string `json:"ip_addr"`
|
||||
Ip6Addr string `json:"ip_6_addr"`
|
||||
|
||||
Admin bool `json:"admin"`
|
||||
}
|
||||
|
||||
type ElasticcachesecgroupDetails struct {
|
||||
ElasticcacheJointResourceDetails
|
||||
|
||||
@@ -353,11 +394,12 @@ type SSecurityGroupRef struct {
|
||||
RdsCnt int `json:"rds_cnt"`
|
||||
RedisCnt int `json:"redis_cnt"`
|
||||
LoadbalancerCnt int `json:"loadbalancer_cnt"`
|
||||
GuestNicCnt int `json:"guest_nic_cnt"`
|
||||
TotalCnt int `json:"total_cnt"`
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupRef) Sum() {
|
||||
self.TotalCnt = self.GuestCnt + self.AdminGuestCnt + self.RdsCnt + self.RedisCnt + self.LoadbalancerCnt
|
||||
self.TotalCnt = self.GuestCnt + self.AdminGuestCnt + self.RdsCnt + self.RedisCnt + self.LoadbalancerCnt + self.GuestNicCnt
|
||||
}
|
||||
|
||||
type SecurityGroupSyncstatusInput struct {
|
||||
|
||||
@@ -328,6 +328,8 @@ func ParseNetworkConfig(desc string, idx int) (*compute.NetworkConfig, error) {
|
||||
}
|
||||
netConfig.Addresses6[i] = addr6.String()
|
||||
}
|
||||
} else if strings.HasPrefix(p, "secgroups=") {
|
||||
netConfig.Secgroups = strings.Split(p[len("secgroups="):], ",")
|
||||
} else if p == "require_designated_ip" {
|
||||
netConfig.RequireDesignatedIP = true
|
||||
} else if p == "random_exit" {
|
||||
|
||||
@@ -3218,6 +3218,13 @@ func (self *SGuest) PerformAttachnetwork(
|
||||
input.Nets[i].Driver = api.NETWORK_DRIVER_VFIO
|
||||
isolatedDevCount += 1
|
||||
}
|
||||
if len(input.Nets[i].Secgroups) > 0 {
|
||||
secgroupIds, err := isValidSecgroups(ctx, userCred, input.Nets[i].Secgroups)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
input.Nets[i].Secgroups = secgroupIds
|
||||
}
|
||||
if input.Nets[i].IsDefault {
|
||||
defaultGwCnt++
|
||||
}
|
||||
@@ -3277,6 +3284,12 @@ func (self *SGuest) PerformAttachnetwork(
|
||||
return nil, errors.Wrap(err, "self.allocSriovNicDevice")
|
||||
}
|
||||
}
|
||||
if len(input.Nets[i].Secgroups) > 0 {
|
||||
err = self.SaveNetworkSecgroups(ctx, userCred, input.Nets[i].Secgroups, gns[0].Index)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SaveNetworkSecgroups")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// adjust default gateway
|
||||
|
||||
@@ -206,6 +206,16 @@ func (manager *SGuestManager) FetchCustomizeColumns(
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(fields) == 0 || fields.Contains("network_secgroups") {
|
||||
gnss := fetchGuestNetworkSecgroups(guestIds)
|
||||
if gnss != nil {
|
||||
for i := range rows {
|
||||
if gns, ok := gnss[guestIds[i]]; ok {
|
||||
rows[i].NetworkSecgroups = gns
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(fields) == 0 || fields.Contains("eip") || fields.Contains("eip_mode") {
|
||||
geips := fetchGuestEips(guestIds)
|
||||
if geips != nil {
|
||||
@@ -759,6 +769,79 @@ func fetchSecgroups(guestIds []string) map[string][]apis.StandaloneShortDesc {
|
||||
return ret
|
||||
}
|
||||
|
||||
func fetchGuestNetworkSecgroups(guestIds []string) map[string][]api.GuestnetworkSecgroupShortDesc {
|
||||
guestnetworks := GuestnetworkManager.Query().SubQuery()
|
||||
guestnetworksecgroups := GuestnetworksecgroupManager.Query().SubQuery()
|
||||
secgroups := SecurityGroupManager.Query().SubQuery()
|
||||
|
||||
q := guestnetworksecgroups.Query(
|
||||
guestnetworksecgroups.Field("guest_id"),
|
||||
guestnetworksecgroups.Field("network_index"),
|
||||
guestnetworksecgroups.Field("secgroup_id"),
|
||||
guestnetworks.Field("mac_addr").Label("mac"),
|
||||
secgroups.Field("name").Label("secgroup_name"),
|
||||
)
|
||||
q = q.Join(guestnetworks, sqlchemy.AND(
|
||||
sqlchemy.Equals(guestnetworks.Field("guest_id"), guestnetworksecgroups.Field("guest_id")),
|
||||
sqlchemy.Equals(guestnetworks.Field("index"), guestnetworksecgroups.Field("network_index")),
|
||||
))
|
||||
q = q.Join(secgroups, sqlchemy.Equals(secgroups.Field("id"), guestnetworksecgroups.Field("secgroup_id")))
|
||||
q = q.Filter(sqlchemy.In(guestnetworksecgroups.Field("guest_id"), guestIds))
|
||||
|
||||
type sGuestNetworkSecgroupInfo struct {
|
||||
GuestId string
|
||||
NetworkIndex int
|
||||
SecgroupId string
|
||||
SecgroupName string
|
||||
Mac string
|
||||
}
|
||||
|
||||
gnss := make([]sGuestNetworkSecgroupInfo, 0)
|
||||
err := q.All(&gnss)
|
||||
if err != nil && errors.Cause(err) != sql.ErrNoRows {
|
||||
log.Errorf("fetchGuestNetworkSecgroups query error: %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
groupedSecgroups := make(map[string][]sGuestNetworkSecgroupInfo)
|
||||
for i := range gnss {
|
||||
groupedSecgroup, ok := groupedSecgroups[gnss[i].GuestId]
|
||||
if !ok {
|
||||
groupedSecgroup = make([]sGuestNetworkSecgroupInfo, 0)
|
||||
}
|
||||
groupedSecgroups[gnss[i].GuestId] = append(groupedSecgroup, gnss[i])
|
||||
}
|
||||
ret := make(map[string][]api.GuestnetworkSecgroupShortDesc)
|
||||
for guestId, secgroups := range groupedSecgroups {
|
||||
networkGroupedSecgroups := make(map[int][]sGuestNetworkSecgroupInfo)
|
||||
for i := range secgroups {
|
||||
secgroupInfos, ok := networkGroupedSecgroups[secgroups[i].NetworkIndex]
|
||||
if !ok {
|
||||
secgroupInfos = make([]sGuestNetworkSecgroupInfo, 0)
|
||||
}
|
||||
networkGroupedSecgroups[secgroups[i].NetworkIndex] = append(secgroupInfos, secgroups[i])
|
||||
}
|
||||
|
||||
guestnetworkSecgroups := make([]api.GuestnetworkSecgroupShortDesc, 0)
|
||||
for networkIndex, secgroups := range networkGroupedSecgroups {
|
||||
//networkSecgroupsDesc := make([]api.GuestnetworkSecgroupShortDesc, 0)
|
||||
nsDesc := api.GuestnetworkSecgroupShortDesc{
|
||||
NetworkIndex: networkIndex,
|
||||
Mac: secgroups[0].Mac,
|
||||
}
|
||||
for i := range secgroups {
|
||||
nsDesc.Secgroups = append(nsDesc.Secgroups, apis.StandaloneShortDesc{
|
||||
Id: secgroups[i].SecgroupId,
|
||||
Name: secgroups[i].SecgroupName,
|
||||
})
|
||||
}
|
||||
guestnetworkSecgroups = append(guestnetworkSecgroups, nsDesc)
|
||||
}
|
||||
ret[guestId] = guestnetworkSecgroups
|
||||
}
|
||||
return ret
|
||||
}
|
||||
|
||||
type sEipInfo struct {
|
||||
IpAddr string
|
||||
Mode string
|
||||
|
||||
@@ -414,3 +414,17 @@ func (guest *SGuest) RevokeAllSecgroups(ctx context.Context, userCred mcclient.T
|
||||
}
|
||||
return guest.saveDefaultSecgroupId(userCred, options.Options.GetDefaultSecurityGroupId(guest.Hypervisor), false)
|
||||
}
|
||||
|
||||
func isValidSecgroups(ctx context.Context, userCred mcclient.TokenCredential, secgroups []string) ([]string, error) {
|
||||
secGrpIds := []string{}
|
||||
for _, secgroup := range secgroups {
|
||||
secGrpObj, err := SecurityGroupManager.FetchByIdOrName(ctx, userCred, secgroup)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Secgroup %s not found", secgroup)
|
||||
}
|
||||
if !utils.IsInStringArray(secGrpObj.GetId(), secGrpIds) {
|
||||
secGrpIds = append(secGrpIds, secGrpObj.GetId())
|
||||
}
|
||||
}
|
||||
return secGrpIds, nil
|
||||
}
|
||||
|
||||
@@ -741,6 +741,21 @@ func (gn *SGuestnetwork) getJsonDesc() *api.GuestnetworkJsonDesc {
|
||||
return desc
|
||||
}
|
||||
|
||||
func (gn *SGuestnetwork) getSecgroupDesc() *api.GuestnetworkSecgroupDesc {
|
||||
secgroupJson, _ := GuestnetworksecgroupManager.getNetworkSecgroupJson(gn.GuestId, gn.Index)
|
||||
if len(secgroupJson) == 0 {
|
||||
return nil
|
||||
}
|
||||
guest := gn.GetGuest()
|
||||
securityRules := guest.getNetworkSecurityGroupsRules(gn.Index)
|
||||
return &api.GuestnetworkSecgroupDesc{
|
||||
Secgroups: secgroupJson,
|
||||
SecurityRules: securityRules,
|
||||
Index: gn.Index,
|
||||
Mac: gn.MacAddr,
|
||||
}
|
||||
}
|
||||
|
||||
func (gn *SGuestnetwork) IsSriovWithoutOffload() bool {
|
||||
if gn.Driver != api.NETWORK_DRIVER_VFIO {
|
||||
return false
|
||||
|
||||
@@ -0,0 +1,644 @@
|
||||
// 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 models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
"strconv"
|
||||
|
||||
"gopkg.in/fatih/set.v0"
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/errors"
|
||||
"yunion.io/x/pkg/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
|
||||
api "yunion.io/x/onecloud/pkg/apis/compute"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/db"
|
||||
"yunion.io/x/onecloud/pkg/cloudcommon/validators"
|
||||
"yunion.io/x/onecloud/pkg/httperrors"
|
||||
"yunion.io/x/onecloud/pkg/mcclient"
|
||||
"yunion.io/x/onecloud/pkg/util/logclient"
|
||||
"yunion.io/x/onecloud/pkg/util/stringutils2"
|
||||
)
|
||||
|
||||
type SGuestnetworksecgroupManager struct {
|
||||
db.SResourceBaseManager
|
||||
SGuestResourceBaseManager
|
||||
SSecurityGroupResourceBaseManager
|
||||
SCloudregionResourceBaseManager
|
||||
SManagedResourceBaseManager
|
||||
SVpcResourceBaseManager
|
||||
}
|
||||
|
||||
var GuestnetworksecgroupManager *SGuestnetworksecgroupManager
|
||||
|
||||
func init() {
|
||||
db.InitManager(func() {
|
||||
GuestnetworksecgroupManager = &SGuestnetworksecgroupManager{
|
||||
SResourceBaseManager: db.NewResourceBaseManager(
|
||||
SGuestnetworksecgroup{},
|
||||
"guestnetworksecgroups_tbl",
|
||||
"guestnetworksecgroup",
|
||||
"guestnetworksecgroups",
|
||||
),
|
||||
}
|
||||
GuestnetworksecgroupManager.SetVirtualObject(GuestnetworksecgroupManager)
|
||||
})
|
||||
}
|
||||
|
||||
type SGuestnetworksecgroup struct {
|
||||
db.SResourceBase
|
||||
|
||||
RowId int64 `primary:"true" auto_increment:"true" list:"user"`
|
||||
|
||||
GuestId string `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required" index:"true"`
|
||||
SSecurityGroupResourceBase `width:"36" charset:"ascii" nullable:"false" list:"user" create:"required"`
|
||||
NetworkIndex int `nullable:"false" list:"user" update:"user"`
|
||||
|
||||
Admin bool `nullable:"false" default:"false" list:"user" create:"optional"`
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) GetSlaveFieldName() string {
|
||||
return "secgroup_id"
|
||||
}
|
||||
|
||||
func (self *SGuestnetworksecgroup) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
return db.DeleteModel(ctx, userCred, self)
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) ListItemFilter(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query api.GuestnetworksecgroupListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SGuestResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ServerFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SGuestJointsManager.ListItemFilter")
|
||||
}
|
||||
q, err = manager.SSecurityGroupResourceBaseManager.ListItemFilter(ctx, q, userCred, query.SecgroupFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SSecurityGroupResourceBaseManager.ListItemFilter")
|
||||
}
|
||||
if query.NetworkIndex != nil {
|
||||
q = q.Equals("network_index", *query.NetworkIndex)
|
||||
}
|
||||
if query.IsAdmin {
|
||||
q = q.IsFalse("admin")
|
||||
}
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) OrderByExtraFields(
|
||||
ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
query api.GuestnetworksecgroupListInput,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SGuestResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ServerFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SGuestJointsManager.OrderByExtraFields")
|
||||
}
|
||||
q, err = manager.SSecurityGroupResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.SecgroupFilterListInput)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SSecurityGroupResourceBaseManager.OrderByExtraFields")
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) ListItemExportKeys(ctx context.Context,
|
||||
q *sqlchemy.SQuery,
|
||||
userCred mcclient.TokenCredential,
|
||||
keys stringutils2.SSortedStrings,
|
||||
) (*sqlchemy.SQuery, error) {
|
||||
var err error
|
||||
|
||||
q, err = manager.SGuestResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SGuestJointsManager.ListItemExportKeys")
|
||||
}
|
||||
if keys.ContainsAny(manager.SSecurityGroupResourceBaseManager.GetExportKeys()...) {
|
||||
q, err = manager.SSecurityGroupResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "SSecurityGroupResourceBaseManager.ListItemExportKeys")
|
||||
}
|
||||
}
|
||||
|
||||
return q, nil
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) FetchCustomizeColumns(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
objs []interface{},
|
||||
fields stringutils2.SSortedStrings,
|
||||
isList bool,
|
||||
) []api.GuestnetworksecgroupDetails {
|
||||
rows := make([]api.GuestnetworksecgroupDetails, len(objs))
|
||||
guestList := make([]interface{}, len(objs))
|
||||
guestIds := make([]string, len(objs))
|
||||
guestNetworkIdx := make([]int, len(objs))
|
||||
secgrpIds := make([]string, len(objs))
|
||||
for i := range objs {
|
||||
secgrpIds[i] = objs[i].(*SGuestnetworksecgroup).SecgroupId
|
||||
guestList[i] = &SGuestResourceBase{objs[i].(*SGuestnetworksecgroup).GuestId}
|
||||
guestIds[i] = objs[i].(*SGuestnetworksecgroup).GuestId
|
||||
guestNetworkIdx[i] = objs[i].(*SGuestnetworksecgroup).NetworkIndex
|
||||
}
|
||||
|
||||
groups := make(map[string]SSecurityGroup)
|
||||
err := db.FetchStandaloneObjectsByIds(SecurityGroupManager, secgrpIds, groups)
|
||||
if err != nil {
|
||||
log.Errorf("FetchStandaloneObjectsByIds fail %s", err)
|
||||
return nil
|
||||
}
|
||||
guestRows := manager.SGuestResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, guestList, fields, isList)
|
||||
gns, err := GuestnetworkManager.fetchGuestnetworksByGuestnetworkIndex(guestIds, guestNetworkIdx)
|
||||
if err != nil {
|
||||
log.Errorf("failed fetchGuestnetworksByGuestnetworkIndex")
|
||||
return nil
|
||||
}
|
||||
|
||||
regionList := make([]interface{}, len(objs))
|
||||
managerList := make([]interface{}, len(objs))
|
||||
vpcList := make([]interface{}, len(objs))
|
||||
projectList := make([]interface{}, len(objs))
|
||||
for i := range rows {
|
||||
secgroupId := objs[i].(*SGuestnetworksecgroup).SecgroupId
|
||||
guestId := objs[i].(*SGuestnetworksecgroup).GuestId
|
||||
networkIndex := objs[i].(*SGuestnetworksecgroup).NetworkIndex
|
||||
|
||||
rows[i].GuestResourceInfo = guestRows[i]
|
||||
rows[i].NetworkIndex = networkIndex
|
||||
rows[i].Admin = objs[i].(*SGuestnetworksecgroup).Admin
|
||||
rows[i].GuestNetwork = path.Join(guestId, secgroupId, strconv.Itoa(rows[i].NetworkIndex))
|
||||
|
||||
if group, ok := groups[secgrpIds[i]]; ok {
|
||||
rows[i].Secgroup = group.Name
|
||||
rows[i].CloudregionId = group.CloudregionId
|
||||
rows[i].ManagerId = group.ManagerId
|
||||
rows[i].VpcId = group.VpcId
|
||||
rows[i].SecgroupStatus = group.Status
|
||||
rows[i].ProjectId = group.ProjectId
|
||||
|
||||
secgroup := group
|
||||
projectList[i] = &secgroup
|
||||
}
|
||||
regionList[i] = &SCloudregionResourceBase{rows[i].CloudregionId}
|
||||
managerList[i] = &SManagedResourceBase{rows[i].ManagerId}
|
||||
vpcList[i] = &SVpcResourceBase{rows[i].VpcId}
|
||||
key := fmt.Sprintf("%s/%d", guestId, networkIndex)
|
||||
if gn, ok := gns[key]; ok {
|
||||
rows[i].MacAddr = gn.MacAddr
|
||||
rows[i].IpAddr = gn.IpAddr
|
||||
rows[i].Ip6Addr = gn.Ip6Addr
|
||||
rows[i].Ifname = gn.Ifname
|
||||
}
|
||||
|
||||
}
|
||||
projRows := SecurityGroupManager.SProjectizedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, projectList, fields, isList)
|
||||
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, regionList, fields, isList)
|
||||
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, managerList, fields, isList)
|
||||
vpcRows := manager.SVpcResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, vpcList, fields, isList)
|
||||
|
||||
for i := range rows {
|
||||
rows[i].ProjectizedResourceInfo = projRows[i]
|
||||
rows[i].CloudregionResourceInfo = regionRows[i]
|
||||
rows[i].ManagedResourceInfo = managerRows[i]
|
||||
rows[i].Vpc = vpcRows[i].Vpc
|
||||
}
|
||||
|
||||
return rows
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworkManager) fetchGuestnetworksByGuestnetworkIndex(guestIds []string, networkIndex []int) (map[string]SGuestnetwork, error) {
|
||||
q := manager.Query()
|
||||
q = q.In("guest_id", guestIds)
|
||||
q = q.In("index", networkIndex)
|
||||
|
||||
gns := make([]SGuestnetwork, 0)
|
||||
err := q.All(&gns)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
res := map[string]SGuestnetwork{}
|
||||
for i := range gns {
|
||||
key := fmt.Sprintf("%s/%d", gns[i].GuestId, gns[i].Index)
|
||||
if _, ok := res[key]; !ok {
|
||||
res[key] = gns[i]
|
||||
}
|
||||
}
|
||||
return res, nil
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = manager.SGuestResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = manager.SSecurityGroupResourceBaseManager.QueryDistinctExtraField(q, field)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
return q, httperrors.ErrNotFound
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) QueryDistinctExtraFields(q *sqlchemy.SQuery, resource string, fields []string) (*sqlchemy.SQuery, error) {
|
||||
q, err := manager.SResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = manager.SGuestResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
q, err = manager.SSecurityGroupResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
|
||||
if err == nil {
|
||||
return q, nil
|
||||
}
|
||||
return q, httperrors.ErrNotFound
|
||||
}
|
||||
|
||||
func (manager *SGuestnetworksecgroupManager) GetGuestnetworksecgroups(guestId string, networkIndex int) ([]SSecurityGroup, error) {
|
||||
q := GuestnetworksecgroupManager.Query("secgroup_id").Equals("guest_id", guestId)
|
||||
if networkIndex >= 0 {
|
||||
q = q.Equals("network_index", networkIndex)
|
||||
}
|
||||
subQ := q.SubQuery()
|
||||
|
||||
secgrpQuery := SecurityGroupManager.Query()
|
||||
secgrpQuery = secgrpQuery.In("id", subQ)
|
||||
|
||||
secgroups := []SSecurityGroup{}
|
||||
err := db.FetchModelObjects(SecurityGroupManager, secgrpQuery, &secgroups)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
return secgroups, nil
|
||||
}
|
||||
|
||||
// guest network attach secgroup
|
||||
func (self *SGuest) PerformAddNetworkSecgroup(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
input api.GuestNetworkAddSecgroupInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING, api.VM_SUSPEND}) {
|
||||
return nil, httperrors.NewInputParameterError("Cannot add security groups in status %s", self.Status)
|
||||
}
|
||||
if input.NetworkIndex == nil || *input.NetworkIndex < 0 {
|
||||
return nil, httperrors.NewBadRequestError("input network index %#v is invalid", input.NetworkIndex)
|
||||
}
|
||||
|
||||
driver, _ := self.GetDriver()
|
||||
maxCount := driver.GetMaxSecurityGroupCount()
|
||||
if maxCount == 0 {
|
||||
return nil, httperrors.NewUnsupportOperationError("Cannot add security groups for hypervisor %s", self.Hypervisor)
|
||||
}
|
||||
|
||||
if len(input.SecgroupIds) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("secgroup_ids")
|
||||
}
|
||||
|
||||
guestnetwork, err := self.getGuestnetworkByIndex(*input.NetworkIndex)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "getGuestnetworkByIndex"))
|
||||
}
|
||||
|
||||
secgroups, err := GuestnetworksecgroupManager.GetGuestnetworksecgroups(self.Id, *input.NetworkIndex)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "GetGuestnetworksecgroups"))
|
||||
}
|
||||
if len(secgroups)+len(input.SecgroupIds) > maxCount {
|
||||
return nil, httperrors.NewUnsupportOperationError("guest %s band to up to %d security groups", self.Name, maxCount)
|
||||
}
|
||||
|
||||
network, err := guestnetwork.GetNetwork()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "GetNetwork"))
|
||||
}
|
||||
|
||||
vpc, err := network.GetVpc()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetVpc")
|
||||
}
|
||||
|
||||
secgroupIds := []string{}
|
||||
for _, secgroup := range secgroups {
|
||||
secgroupIds = append(secgroupIds, secgroup.Id)
|
||||
}
|
||||
|
||||
secgroupNames := []string{}
|
||||
for i := range input.SecgroupIds {
|
||||
secObj, err := validators.ValidateModel(ctx, userCred, SecurityGroupManager, &input.SecgroupIds[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secgroup := secObj.(*SSecurityGroup)
|
||||
|
||||
if utils.IsInStringArray(secObj.GetId(), secgroupIds) {
|
||||
return nil, httperrors.NewInputParameterError(
|
||||
"security group %s has already been assigned to guest %s network %d",
|
||||
secObj.GetName(), self.GetName(), input.NetworkIndex)
|
||||
}
|
||||
|
||||
err = vpc.CheckSecurityGroupConsistent(secgroup)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
secgroupIds = append(secgroupIds, secgroup.GetId())
|
||||
secgroupNames = append(secgroupNames, secgroup.Name)
|
||||
}
|
||||
|
||||
err = self.SaveNetworkSecgroups(ctx, userCred, secgroupIds, *input.NetworkIndex)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "SaveNetworkSecgroups"))
|
||||
}
|
||||
|
||||
notes := map[string][]string{"secgroups": secgroupNames}
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_VM_ASSIGNSECGROUP, notes, userCred, true)
|
||||
return nil, self.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformRevokeNetworkSecgroup(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
input api.GuestRevokeNetworkSecgroupInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING, api.VM_SUSPEND}) {
|
||||
return nil, httperrors.NewInputParameterError("Cannot revoke security groups in status %s", self.Status)
|
||||
}
|
||||
if len(input.SecgroupIds) == 0 {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var guestnetwork *SGuestnetwork
|
||||
var err error
|
||||
|
||||
if input.MacAddr != "" {
|
||||
guestnetwork, err = self.GetGuestnetworkByMac(input.MacAddr)
|
||||
} else if input.NetworkIndex != nil {
|
||||
guestnetwork, err = self.getGuestnetworkByIndex(*input.NetworkIndex)
|
||||
} else {
|
||||
return nil, httperrors.NewBadRequestError("no valid network index or mac addr")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "get guest network"))
|
||||
}
|
||||
|
||||
secgroups, err := GuestnetworksecgroupManager.GetGuestnetworksecgroups(self.Id, guestnetwork.Index)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "GetGuestnetworksecgroups"))
|
||||
}
|
||||
secgroupMaps := map[string]string{}
|
||||
for _, secgroup := range secgroups {
|
||||
secgroupMaps[secgroup.Id] = secgroup.Name
|
||||
}
|
||||
|
||||
secgroupNames := []string{}
|
||||
for i := range input.SecgroupIds {
|
||||
secObj, err := validators.ValidateModel(ctx, userCred, SecurityGroupManager, &input.SecgroupIds[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secgrp := secObj.(*SSecurityGroup)
|
||||
_, ok := secgroupMaps[secgrp.GetId()]
|
||||
if !ok {
|
||||
return nil, httperrors.NewInputParameterError("security group %s network index %d not assigned to guest %s",
|
||||
secgrp.GetName(), guestnetwork.Index, self.GetName())
|
||||
}
|
||||
delete(secgroupMaps, secgrp.GetId())
|
||||
secgroupNames = append(secgroupNames, secgrp.GetName())
|
||||
}
|
||||
|
||||
secgrpIds := []string{}
|
||||
for secgroupId := range secgroupMaps {
|
||||
secgrpIds = append(secgrpIds, secgroupId)
|
||||
}
|
||||
|
||||
err = self.SaveNetworkSecgroups(ctx, userCred, secgrpIds, guestnetwork.Index)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "SaveNetworkSecgroups"))
|
||||
}
|
||||
|
||||
notes := map[string][]string{"secgroups": secgroupNames}
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_VM_REVOKESECGROUP, notes, userCred, true)
|
||||
return nil, self.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
|
||||
func (self *SGuest) PerformSetNetworkSecgroup(
|
||||
ctx context.Context,
|
||||
userCred mcclient.TokenCredential,
|
||||
query jsonutils.JSONObject,
|
||||
input api.GuestSetNetworkSecgroupInput,
|
||||
) (jsonutils.JSONObject, error) {
|
||||
if !utils.IsInStringArray(self.Status, []string{api.VM_READY, api.VM_RUNNING, api.VM_SUSPEND}) {
|
||||
return nil, httperrors.NewInputParameterError("Cannot set security rules in status %s", self.Status)
|
||||
}
|
||||
if len(input.SecgroupIds) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("secgroup_ids")
|
||||
}
|
||||
|
||||
driver, _ := self.GetDriver()
|
||||
maxCount := driver.GetMaxSecurityGroupCount()
|
||||
if maxCount == 0 {
|
||||
return nil, httperrors.NewUnsupportOperationError("Cannot set security group for this guest %s", self.Name)
|
||||
}
|
||||
|
||||
if len(input.SecgroupIds) > maxCount {
|
||||
return nil, httperrors.NewUnsupportOperationError("guest %s band to up to %d security groups", self.Name, maxCount)
|
||||
}
|
||||
|
||||
var guestnetwork *SGuestnetwork
|
||||
var err error
|
||||
|
||||
if input.MacAddr != "" {
|
||||
guestnetwork, err = self.GetGuestnetworkByMac(input.MacAddr)
|
||||
} else if input.NetworkIndex != nil {
|
||||
guestnetwork, err = self.getGuestnetworkByIndex(*input.NetworkIndex)
|
||||
} else {
|
||||
return nil, httperrors.NewBadRequestError("no valid network index or mac addr")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "get guest network"))
|
||||
}
|
||||
|
||||
network, err := guestnetwork.GetNetwork()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrap(err, "GetNetwork"))
|
||||
}
|
||||
|
||||
vpc, err := network.GetVpc()
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetVpc")
|
||||
}
|
||||
|
||||
secgroupIds := []string{}
|
||||
secgroupNames := []string{}
|
||||
for i := range input.SecgroupIds {
|
||||
secObj, err := validators.ValidateModel(ctx, userCred, SecurityGroupManager, &input.SecgroupIds[i])
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
secgrp := secObj.(*SSecurityGroup)
|
||||
|
||||
err = vpc.CheckSecurityGroupConsistent(secgrp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if !utils.IsInStringArray(secgrp.GetId(), secgroupIds) {
|
||||
secgroupIds = append(secgroupIds, secgrp.GetId())
|
||||
secgroupNames = append(secgroupNames, secgrp.GetName())
|
||||
}
|
||||
}
|
||||
|
||||
err = self.SaveNetworkSecgroups(ctx, userCred, secgroupIds, guestnetwork.Index)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewGeneralError(errors.Wrapf(err, "SaveNetworkSecgroups"))
|
||||
}
|
||||
|
||||
notes := map[string][]string{"secgroups": secgroupNames}
|
||||
logclient.AddActionLogWithContext(ctx, self, logclient.ACT_VM_SETSECGROUP, notes, userCred, true)
|
||||
return nil, self.StartSyncTask(ctx, userCred, true, "")
|
||||
}
|
||||
|
||||
func (self *SGuest) SaveNetworkSecgroups(
|
||||
ctx context.Context, userCred mcclient.TokenCredential, secgroupIds []string, networkIndex int,
|
||||
) error {
|
||||
if len(secgroupIds) == 0 {
|
||||
return self.RevokeNetworkAllSecgroups(ctx, userCred, networkIndex)
|
||||
}
|
||||
oldIds := set.New(set.ThreadSafe)
|
||||
newIds := set.New(set.ThreadSafe)
|
||||
gnss, err := self.GetGuestNetworkSecgroups(networkIndex)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetGuestNetworkSecgroups")
|
||||
}
|
||||
secgroupMaps := map[string]SGuestnetworksecgroup{}
|
||||
for i := range gnss {
|
||||
oldIds.Add(gnss[i].SecgroupId)
|
||||
secgroupMaps[gnss[i].SecgroupId] = gnss[i]
|
||||
}
|
||||
for i := range secgroupIds {
|
||||
newIds.Add(secgroupIds[i])
|
||||
}
|
||||
for _, removed := range set.Difference(oldIds, newIds).List() {
|
||||
id := removed.(string)
|
||||
gns, ok := secgroupMaps[id]
|
||||
if ok {
|
||||
err = gns.Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err,
|
||||
"Delete guest network secgroup for guest %s network index %d secgroup %s",
|
||||
self.GetName(), networkIndex, id)
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, added := range set.Difference(newIds, oldIds).List() {
|
||||
id := added.(string)
|
||||
err = self.newGuestNetworkSecgroup(ctx, id, networkIndex, false)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err,
|
||||
"New guest network secgroup for guest %s network index %d with secgroup %s",
|
||||
self.GetName(), networkIndex, id)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuest) newGuestNetworkSecgroup(ctx context.Context, secgroupId string, networkIndex int, isAdmin bool) error {
|
||||
gns := &SGuestnetworksecgroup{}
|
||||
gns.SetModelManager(GuestnetworksecgroupManager, gns)
|
||||
gns.GuestId = self.Id
|
||||
gns.SecgroupId = secgroupId
|
||||
gns.NetworkIndex = networkIndex
|
||||
gns.Admin = isAdmin
|
||||
return GuestnetworksecgroupManager.TableSpec().Insert(ctx, gns)
|
||||
}
|
||||
|
||||
func (self *SGuest) GetGuestNetworkSecgroups(networkIndex int) ([]SGuestnetworksecgroup, error) {
|
||||
gss := []SGuestnetworksecgroup{}
|
||||
q := GuestnetworksecgroupManager.Query().Equals("guest_id", self.Id).Equals("network_index", networkIndex)
|
||||
err := db.FetchModelObjects(GuestnetworksecgroupManager, q, &gss)
|
||||
if err != nil {
|
||||
return nil, errors.Wrapf(err, "db.FetchModelObjects")
|
||||
}
|
||||
return gss, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) RevokeNetworkAllSecgroups(ctx context.Context, userCred mcclient.TokenCredential, networkIndex int) error {
|
||||
gss, err := self.GetGuestNetworkSecgroups(networkIndex)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "GetGuestNetworkSecgroups")
|
||||
}
|
||||
for i := range gss {
|
||||
err = gss[i].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Delete")
|
||||
}
|
||||
}
|
||||
|
||||
//return self.newGuestNetworkSecgroup(ctx, options.Options.DefaultSecurityGroupId, networkIndex, false)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (self *SGuestnetworksecgroupManager) getNetworkSecgroupJson(guestId string, networkIndex int) ([]*api.SecgroupJsonDesc, error) {
|
||||
ret := []*api.SecgroupJsonDesc{}
|
||||
secgroups, err := GuestnetworksecgroupManager.GetGuestnetworksecgroups(guestId, networkIndex)
|
||||
if err != nil {
|
||||
return nil, errors.Wrap(err, "GetSecgroups")
|
||||
}
|
||||
for _, secGrp := range secgroups {
|
||||
ret = append(ret, secGrp.getDesc())
|
||||
}
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (self *SGuest) RevokeAllNetworkSecgroups(ctx context.Context, userCred mcclient.TokenCredential) error {
|
||||
gns, err := self.GetNetworks("")
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetNetworks")
|
||||
}
|
||||
for i := range gns {
|
||||
gnss, err := self.GetGuestNetworkSecgroups(gns[i].Index)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "GetGuestNetworkSecgroups")
|
||||
}
|
||||
for j := range gnss {
|
||||
err = gnss[j].Delete(ctx, userCred)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "Delete guestnetworksecgroup")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -32,7 +32,7 @@ import (
|
||||
)
|
||||
|
||||
type SGuestResourceBase struct {
|
||||
GuestId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional"`
|
||||
GuestId string `width:"36" charset:"ascii" nullable:"true" list:"user" create:"optional" json:"guest_id"`
|
||||
}
|
||||
|
||||
type SGuestResourceBaseManager struct {
|
||||
@@ -98,7 +98,7 @@ func (manager *SGuestResourceBaseManager) FetchCustomizeColumns(
|
||||
var base *SGuestResourceBase
|
||||
err := reflectutils.FindAnonymouStructPointer(objs[i], &base)
|
||||
if err != nil {
|
||||
log.Errorf("Cannot find SGuestResourceBase in object %s", objs[i])
|
||||
log.Errorf("Cannot find SGuestResourceBase in object %s %s", objs[i], err)
|
||||
continue
|
||||
}
|
||||
guestIds[i] = base.GuestId
|
||||
|
||||
@@ -1225,6 +1225,18 @@ func (guest *SGuest) ConvertEsxiNetworks(targetGuest *SGuest) error {
|
||||
return err
|
||||
}
|
||||
|
||||
func (guest *SGuest) getGuestnetworkByIndex(networkIndex int) (*SGuestnetwork, error) {
|
||||
q := guest.GetNetworksQuery("").Equals("index", networkIndex)
|
||||
|
||||
guestnic := SGuestnetwork{}
|
||||
err := q.First(&guestnic)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
guestnic.SetModelManager(GuestnetworkManager, &guestnic)
|
||||
return &guestnic, nil
|
||||
}
|
||||
|
||||
func (guest *SGuest) getGuestnetworkByIpOrMac(ipAddr string, ip6Addr string, macAddr string) (*SGuestnetwork, error) {
|
||||
q := guest.GetNetworksQuery("")
|
||||
if len(ipAddr) > 0 {
|
||||
@@ -2142,6 +2154,11 @@ func (manager *SGuestManager) validateCreateData(
|
||||
netConfig.SriovDevice = devConfig
|
||||
netConfig.Driver = api.NETWORK_DRIVER_VFIO
|
||||
}
|
||||
secgroupIds, err := isValidSecgroups(ctx, userCred, netConfig.Secgroups)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
netConfig.Secgroups = secgroupIds
|
||||
|
||||
netConfig.Project = ownerId.GetProjectId()
|
||||
netConfig.Domain = ownerId.GetProjectDomainId()
|
||||
@@ -2208,15 +2225,9 @@ func (manager *SGuestManager) validateCreateData(
|
||||
input.KeypairId = keypairObj.GetId()
|
||||
}
|
||||
|
||||
secGrpIds := []string{}
|
||||
for _, secgroup := range input.Secgroups {
|
||||
secGrpObj, err := SecurityGroupManager.FetchByIdOrName(ctx, userCred, secgroup)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewResourceNotFoundError("Secgroup %s not found", secgroup)
|
||||
}
|
||||
if !utils.IsInStringArray(secGrpObj.GetId(), secGrpIds) {
|
||||
secGrpIds = append(secGrpIds, secGrpObj.GetId())
|
||||
}
|
||||
secGrpIds, err := isValidSecgroups(ctx, userCred, input.Secgroups)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(secGrpIds) > 0 {
|
||||
input.SecgroupId = secGrpIds[0]
|
||||
@@ -3348,6 +3359,26 @@ func (self *SGuest) getSecurityGroupsRules() string {
|
||||
return strings.Join(rules, SECURITY_GROUP_SEPARATOR)
|
||||
}
|
||||
|
||||
func (self *SGuest) getNetworkSecurityGroupsRules(networkIndex int) string {
|
||||
gnss, _ := self.GetGuestNetworkSecgroups(networkIndex)
|
||||
secgroupids := []string{}
|
||||
for _, gns := range gnss {
|
||||
secgroupids = append(secgroupids, gns.SecgroupId)
|
||||
}
|
||||
q := SecurityGroupRuleManager.Query()
|
||||
q.Filter(sqlchemy.In(q.Field("secgroup_id"), secgroupids)).Desc(q.Field("priority"), q.Field("action"))
|
||||
secrules := []SSecurityGroupRule{}
|
||||
if err := db.FetchModelObjects(SecurityGroupRuleManager, q, &secrules); err != nil {
|
||||
log.Errorf("Get security group rules error: %v", err)
|
||||
return ""
|
||||
}
|
||||
rules := []string{}
|
||||
for _, rule := range secrules {
|
||||
rules = append(rules, rule.String())
|
||||
}
|
||||
return strings.Join(rules, SECURITY_GROUP_SEPARATOR)
|
||||
}
|
||||
|
||||
func (self *SGuest) getAdminSecurityRules() string {
|
||||
secgrp := self.getAdminSecgroup()
|
||||
if secgrp != nil {
|
||||
@@ -4674,7 +4705,12 @@ func (self *SGuest) CreateNetworksOnHost(
|
||||
return errors.Wrap(err, "self.allocSriovNicDevice")
|
||||
}
|
||||
}
|
||||
|
||||
if len(netConfig.Secgroups) > 0 {
|
||||
err = self.SaveNetworkSecgroups(ctx, userCred, netConfig.Secgroups, gns[0].Index)
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "SaveNetworkSecgroups")
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -5630,6 +5666,13 @@ func (self *SGuest) GetJsonDescAtHypervisor(ctx context.Context, host *SHost) *a
|
||||
if len(nicDesc.Domain) > 0 {
|
||||
desc.Domain = nicDesc.Domain
|
||||
}
|
||||
secgroupDesc := nic.getSecgroupDesc()
|
||||
if secgroupDesc != nil {
|
||||
if desc.NicSecgroups == nil {
|
||||
desc.NicSecgroups = make([]*api.GuestnetworkSecgroupDesc, 0)
|
||||
}
|
||||
desc.NicSecgroups = append(desc.NicSecgroups, secgroupDesc)
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
@@ -104,6 +104,7 @@ func (manager *SSecurityGroupResourceBaseManager) FetchCustomizeColumns(
|
||||
|
||||
regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, regionList, fields, isList)
|
||||
managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, managerList, fields, isList)
|
||||
|
||||
for i := range rows {
|
||||
rows[i].CloudregionResourceInfo = regionRows[i]
|
||||
rows[i].ManagedResourceInfo = managerRows[i]
|
||||
|
||||
@@ -410,6 +410,7 @@ func (manager *SSecurityGroupManager) FetchCustomizeColumns(
|
||||
adminGuestMaps := map[string]int{}
|
||||
systemGuestMaps := map[string]int{}
|
||||
normalGuestMaps := map[string]int{}
|
||||
guestNetworkMaps := map[string]int{}
|
||||
for i := range guests {
|
||||
if guests[i].IsSystem {
|
||||
if _, ok := systemGuestMaps[guests[i].SecgrpId]; !ok {
|
||||
@@ -456,6 +457,22 @@ func (manager *SSecurityGroupManager) FetchCustomizeColumns(
|
||||
return rows
|
||||
}
|
||||
|
||||
gnq := GuestnetworksecgroupManager.Query()
|
||||
gq := GuestManager.Query().IsFalse("pending_deleted").SubQuery()
|
||||
gnq = gnq.Join(gq, sqlchemy.Equals(gnq.Field("guest_id"), gq.Field("id")))
|
||||
guestNetworkSecgroups := []SGuestnetworksecgroup{}
|
||||
err = db.FetchModelObjects(GuestnetworksecgroupManager, gnq, &guestNetworkSecgroups)
|
||||
if err != nil {
|
||||
log.Errorf("db.FetchModelObjects error: %v", err)
|
||||
return rows
|
||||
}
|
||||
for i := range guestNetworkSecgroups {
|
||||
if _, ok := guestNetworkMaps[guestNetworkSecgroups[i].SecgroupId]; !ok {
|
||||
guestNetworkMaps[guestNetworkSecgroups[i].SecgroupId] = 0
|
||||
}
|
||||
guestNetworkMaps[guestNetworkSecgroups[i].SecgroupId]++
|
||||
}
|
||||
|
||||
totalCnt, err := manager.TotalCnt(secgroupIds)
|
||||
if err != nil {
|
||||
return rows
|
||||
@@ -464,6 +481,7 @@ func (manager *SSecurityGroupManager) FetchCustomizeColumns(
|
||||
rows[i].GuestCnt, _ = normalGuestMaps[secgroupIds[i]]
|
||||
rows[i].AdminGuestCnt, _ = adminGuestMaps[secgroupIds[i]]
|
||||
rows[i].SystemGuestCnt, _ = systemGuestMaps[secgroupIds[i]]
|
||||
rows[i].GuestNicCnt, _ = guestNetworkMaps[secgroupIds[i]]
|
||||
if cnt, ok := totalCnt[secgroupIds[i]]; ok {
|
||||
rows[i].TotalCnt = cnt.TotalCnt
|
||||
rows[i].LoadbalancerCnt = cnt.LoadbalancerCnt
|
||||
@@ -1003,6 +1021,7 @@ func (sm *SSecurityGroupManager) TotalCnt(secIds []string) (map[string]api.SSecu
|
||||
g1SQ := sm.query(GuestsecgroupManager, "secgroup_id", "guest1", secIds)
|
||||
g2SQ := sm.query(GuestManager, "secgrp_id", "guest2", secIds)
|
||||
g3SQ := sm.query(GuestManager, "admin_secgrp_id", "guest3", secIds)
|
||||
g4SQ := sm.query(GuestnetworksecgroupManager, "secgroup_id", "guest4", secIds)
|
||||
|
||||
rdsSQ := sm.query(DBInstanceSecgroupManager, "secgroup_id", "rds", secIds)
|
||||
redisSQ := sm.query(ElasticcachesecgroupManager, "secgroup_id", "redis", secIds)
|
||||
@@ -1016,6 +1035,7 @@ func (sm *SSecurityGroupManager) TotalCnt(secIds []string) (map[string]api.SSecu
|
||||
sqlchemy.SUM("rds_cnt", rdsSQ.Field("rds")),
|
||||
sqlchemy.SUM("redis_cnt", redisSQ.Field("redis")),
|
||||
sqlchemy.SUM("loadbalancer_cnt", lbSQ.Field("loadbalancer")),
|
||||
sqlchemy.SUM("guest_nic_cnt", g4SQ.Field("guest4")),
|
||||
)
|
||||
|
||||
secQ.AppendField(secQ.Field("id"))
|
||||
@@ -1026,6 +1046,7 @@ func (sm *SSecurityGroupManager) TotalCnt(secIds []string) (map[string]api.SSecu
|
||||
secQ = secQ.LeftJoin(rdsSQ, sqlchemy.Equals(secQ.Field("id"), rdsSQ.Field("secgroup_id")))
|
||||
secQ = secQ.LeftJoin(redisSQ, sqlchemy.Equals(secQ.Field("id"), redisSQ.Field("secgroup_id")))
|
||||
secQ = secQ.LeftJoin(lbSQ, sqlchemy.Equals(secQ.Field("id"), lbSQ.Field("secgroup_id")))
|
||||
secQ = secQ.LeftJoin(g4SQ, sqlchemy.Equals(secQ.Field("id"), g4SQ.Field("secgroup_id")))
|
||||
|
||||
secQ = secQ.Filter(sqlchemy.In(secQ.Field("id"), secIds)).GroupBy(secQ.Field("id"))
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ func InitHandlers(app *appsrv.Application, isSlave bool) {
|
||||
models.InterVpcNetworkRouteSetManager,
|
||||
models.GuestScreenDumpManager,
|
||||
models.BillingResourceCheckManager,
|
||||
models.GuestnetworksecgroupManager,
|
||||
|
||||
models.SchedpolicyManager,
|
||||
models.DynamicschedtagManager,
|
||||
|
||||
@@ -340,6 +340,7 @@ func (deleteTask *BaseGuestDeleteTask) OnGuestDeleteCompleteFailed(ctx context.C
|
||||
|
||||
func (deleteTask *BaseGuestDeleteTask) OnGuestDeleteComplete(ctx context.Context, obj db.IStandaloneModel, data jsonutils.JSONObject) {
|
||||
guest := obj.(*models.SGuest)
|
||||
guest.RevokeAllNetworkSecgroups(ctx, deleteTask.UserCred)
|
||||
guest.DetachAllNetworks(ctx, deleteTask.UserCred)
|
||||
guest.EjectAllIso(deleteTask.UserCred)
|
||||
guest.EjectAllVfd(deleteTask.UserCred)
|
||||
|
||||
@@ -379,11 +379,13 @@ type SGuestControlDesc struct {
|
||||
// is volatile host meaning guest not running on this host right now
|
||||
IsVolatileHost bool
|
||||
|
||||
ScalingGroupId string
|
||||
ScalingGroupId string
|
||||
SrcIpCheck bool
|
||||
SrcMacCheck bool
|
||||
|
||||
SecurityRules string
|
||||
AdminSecurityRules string
|
||||
SrcIpCheck bool
|
||||
SrcMacCheck bool
|
||||
NicSecgroups []*api.GuestnetworkSecgroupDesc `json:"nic_secgroups,omitempty"`
|
||||
|
||||
EncryptKeyId string
|
||||
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// 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 compute
|
||||
|
||||
import (
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modulebase"
|
||||
"yunion.io/x/onecloud/pkg/mcclient/modules"
|
||||
)
|
||||
|
||||
var (
|
||||
Servernetworksecgroups modulebase.ResourceManager
|
||||
)
|
||||
|
||||
func init() {
|
||||
Servernetworksecgroups = modules.NewComputeManager(
|
||||
"guestnetworksecgroup",
|
||||
"guestnetworksecgroups",
|
||||
[]string{"Guest_id", "Network_index", "Secgroup_id", "Admin"},
|
||||
[]string{})
|
||||
modules.RegisterCompute(&Servernetworksecgroups)
|
||||
}
|
||||
@@ -197,3 +197,16 @@ type SecgroupCleanOptions struct {
|
||||
func (opts *SecgroupCleanOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
type ServerNetworkSecgroupListOptions struct {
|
||||
baseoptions.BaseListOptions
|
||||
|
||||
Server string `help:"Server Id or name"`
|
||||
Secgroup string `help:"Secgroup Id or name"`
|
||||
NetworkIndex *int `help:"Server network index"`
|
||||
IsAdmin bool `help:"Is admin secgroup"`
|
||||
}
|
||||
|
||||
func (opts *ServerNetworkSecgroupListOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return baseoptions.ListStructToParams(opts)
|
||||
}
|
||||
|
||||
@@ -894,6 +894,20 @@ func (opts *ServerSecGroupsOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(map[string][]string{"secgroup_ids": opts.SecgroupIds}), nil
|
||||
}
|
||||
|
||||
type ServerNetworkSecGroupsOptions struct {
|
||||
ID string `help:"ID or Name of server" metavar:"Guest" json:"-"`
|
||||
NetworkIndex *int `help:"Guest network index" metavar:"Network Index"`
|
||||
SecgroupIds []string `help:"Ids of Security Groups" metavar:"Security Groups" positional:"true"`
|
||||
}
|
||||
|
||||
func (o *ServerNetworkSecGroupsOptions) GetId() string {
|
||||
return o.ID
|
||||
}
|
||||
|
||||
func (opts *ServerNetworkSecGroupsOptions) Params() (jsonutils.JSONObject, error) {
|
||||
return jsonutils.Marshal(opts), nil
|
||||
}
|
||||
|
||||
type ServerModifySrcCheckOptions struct {
|
||||
ID string `help:"ID or Name of server" metavar:"Guest" json:"-"`
|
||||
SrcIpCheck string `help:"Turn on/off src ip check" choices:"on|off"`
|
||||
|
||||
@@ -88,6 +88,9 @@ type Guestnetwork struct {
|
||||
Network *Network `json:"-"`
|
||||
Elasticip *Elasticip `json:"-"`
|
||||
SubIPs NetworkAddresses `json:"-"`
|
||||
|
||||
// guest nic level secgroup
|
||||
Guestnetworksecgroups Guestnetworksecgroups `json:"-"`
|
||||
}
|
||||
|
||||
func (el *Guestnetwork) Copy() *Guestnetwork {
|
||||
@@ -109,6 +112,22 @@ func (el *NetworkAddress) Copy() *NetworkAddress {
|
||||
}
|
||||
}
|
||||
|
||||
type Guestnetworksecgroup struct {
|
||||
compute_models.SGuestnetworksecgroup
|
||||
|
||||
SecurityGroup *SecurityGroup `json:"-"`
|
||||
}
|
||||
|
||||
func (el *Guestnetworksecgroup) ModelSetKey() string {
|
||||
return fmt.Sprintf("%s/%d", el.GuestId, el.NetworkIndex)
|
||||
}
|
||||
|
||||
func (el *Guestnetworksecgroup) Copy() *Guestnetworksecgroup {
|
||||
return &Guestnetworksecgroup{
|
||||
SGuestnetworksecgroup: el.SGuestnetworksecgroup,
|
||||
}
|
||||
}
|
||||
|
||||
type Guest struct {
|
||||
compute_models.SGuest
|
||||
|
||||
|
||||
@@ -39,8 +39,9 @@ type (
|
||||
Elasticips map[string]*Elasticip
|
||||
NetworkAddresses map[string]*NetworkAddress
|
||||
|
||||
Guestnetworks map[string]*Guestnetwork // key: rowId
|
||||
Guestsecgroups map[string]*Guestsecgroup // key: guestId/secgroupId
|
||||
Guestnetworks map[string]*Guestnetwork // key: rowId
|
||||
Guestsecgroups map[string]*Guestsecgroup // key: guestId/secgroupId
|
||||
Guestnetworksecgroups map[string]*Guestnetworksecgroup // key: guestId/networkIndex
|
||||
|
||||
DnsZones map[string]*DnsZone
|
||||
DnsRecords map[string]*DnsRecord
|
||||
@@ -583,6 +584,59 @@ func (set Guestnetworks) joinNetworkAddresses(subEntries NetworkAddresses) bool
|
||||
return correct
|
||||
}
|
||||
|
||||
func (set Guestnetworks) joinGuestnetworksecgroups(subEntries Guestnetworksecgroups) bool {
|
||||
for _, gn := range set {
|
||||
key := fmt.Sprintf("%s/%d", gn.GuestId, gn.Index)
|
||||
gns, ok := subEntries[key]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
if len(gn.Guestnetworksecgroups) == 0 {
|
||||
gn.Guestnetworksecgroups = Guestnetworksecgroups{}
|
||||
}
|
||||
gn.Guestnetworksecgroups[key] = gns
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (set Guestnetworksecgroups) ModelManager() mcclient_modulebase.IBaseManager {
|
||||
return &mcclient_modules.Servernetworksecgroups
|
||||
}
|
||||
|
||||
func (set Guestnetworksecgroups) DBModelManager() db.IModelManager {
|
||||
return models.GuestnetworksecgroupManager
|
||||
}
|
||||
|
||||
func (set Guestnetworksecgroups) NewModel() db.IModel {
|
||||
return &Guestnetworksecgroup{}
|
||||
}
|
||||
|
||||
func (set Guestnetworksecgroups) AddModel(i db.IModel) {
|
||||
m := i.(*Guestnetworksecgroup)
|
||||
k := m.ModelSetKey()
|
||||
set[k] = m
|
||||
}
|
||||
|
||||
func (set Guestnetworksecgroups) Copy() apihelper.IModelSet {
|
||||
setCopy := Guestnetworksecgroups{}
|
||||
for id, el := range set {
|
||||
setCopy[id] = el.Copy()
|
||||
}
|
||||
return setCopy
|
||||
}
|
||||
|
||||
func (set Guestnetworksecgroups) joinSecurityGroups(subEntries SecurityGroups) bool {
|
||||
for _, gns := range set {
|
||||
key := gns.SecgroupId
|
||||
secgroup, ok := subEntries[key]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
gns.SecurityGroup = secgroup
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (set NetworkAddresses) ModelManager() mcclient_modulebase.IBaseManager {
|
||||
return &mcclient_modules.NetworkAddresses
|
||||
}
|
||||
|
||||
@@ -27,17 +27,18 @@ import (
|
||||
)
|
||||
|
||||
type ModelSetsMaxUpdatedAt struct {
|
||||
Vpcs time.Time
|
||||
Wires time.Time
|
||||
Networks time.Time
|
||||
Guests time.Time
|
||||
Hosts time.Time
|
||||
SecurityGroups time.Time
|
||||
SecurityGroupRules time.Time
|
||||
Guestnetworks time.Time
|
||||
Guestsecgroups time.Time
|
||||
Elasticips time.Time
|
||||
NetworkAddresses time.Time
|
||||
Vpcs time.Time
|
||||
Wires time.Time
|
||||
Networks time.Time
|
||||
Guests time.Time
|
||||
Hosts time.Time
|
||||
SecurityGroups time.Time
|
||||
SecurityGroupRules time.Time
|
||||
Guestnetworks time.Time
|
||||
Guestsecgroups time.Time
|
||||
Elasticips time.Time
|
||||
NetworkAddresses time.Time
|
||||
Guestnetworksecgroups time.Time
|
||||
|
||||
DnsZones time.Time
|
||||
DnsRecords time.Time
|
||||
@@ -54,17 +55,18 @@ type ModelSetsMaxUpdatedAt struct {
|
||||
|
||||
func NewModelSetsMaxUpdatedAt() *ModelSetsMaxUpdatedAt {
|
||||
return &ModelSetsMaxUpdatedAt{
|
||||
Vpcs: apihelper.PseudoZeroTime,
|
||||
Wires: apihelper.PseudoZeroTime,
|
||||
Networks: apihelper.PseudoZeroTime,
|
||||
Guests: apihelper.PseudoZeroTime,
|
||||
Hosts: apihelper.PseudoZeroTime,
|
||||
SecurityGroups: apihelper.PseudoZeroTime,
|
||||
SecurityGroupRules: apihelper.PseudoZeroTime,
|
||||
Guestnetworks: apihelper.PseudoZeroTime,
|
||||
Guestsecgroups: apihelper.PseudoZeroTime,
|
||||
Elasticips: apihelper.PseudoZeroTime,
|
||||
NetworkAddresses: apihelper.PseudoZeroTime,
|
||||
Vpcs: apihelper.PseudoZeroTime,
|
||||
Wires: apihelper.PseudoZeroTime,
|
||||
Networks: apihelper.PseudoZeroTime,
|
||||
Guests: apihelper.PseudoZeroTime,
|
||||
Hosts: apihelper.PseudoZeroTime,
|
||||
SecurityGroups: apihelper.PseudoZeroTime,
|
||||
SecurityGroupRules: apihelper.PseudoZeroTime,
|
||||
Guestnetworks: apihelper.PseudoZeroTime,
|
||||
Guestsecgroups: apihelper.PseudoZeroTime,
|
||||
Elasticips: apihelper.PseudoZeroTime,
|
||||
NetworkAddresses: apihelper.PseudoZeroTime,
|
||||
Guestnetworksecgroups: apihelper.PseudoZeroTime,
|
||||
|
||||
DnsZones: apihelper.PseudoZeroTime,
|
||||
DnsRecords: apihelper.PseudoZeroTime,
|
||||
@@ -81,17 +83,18 @@ func NewModelSetsMaxUpdatedAt() *ModelSetsMaxUpdatedAt {
|
||||
}
|
||||
|
||||
type ModelSets struct {
|
||||
Vpcs Vpcs
|
||||
Wires Wires
|
||||
Networks Networks
|
||||
Guests Guests
|
||||
Hosts Hosts
|
||||
SecurityGroups SecurityGroups
|
||||
SecurityGroupRules SecurityGroupRules
|
||||
Guestnetworks Guestnetworks
|
||||
Guestsecgroups Guestsecgroups
|
||||
Elasticips Elasticips
|
||||
NetworkAddresses NetworkAddresses
|
||||
Vpcs Vpcs
|
||||
Wires Wires
|
||||
Networks Networks
|
||||
Guests Guests
|
||||
Hosts Hosts
|
||||
SecurityGroups SecurityGroups
|
||||
SecurityGroupRules SecurityGroupRules
|
||||
Guestnetworks Guestnetworks
|
||||
Guestsecgroups Guestsecgroups
|
||||
Elasticips Elasticips
|
||||
NetworkAddresses NetworkAddresses
|
||||
Guestnetworksecgroups Guestnetworksecgroups
|
||||
|
||||
DnsZones DnsZones
|
||||
DnsRecords DnsRecords
|
||||
@@ -109,17 +112,18 @@ type ModelSets struct {
|
||||
|
||||
func NewModelSets() *ModelSets {
|
||||
return &ModelSets{
|
||||
Vpcs: Vpcs{},
|
||||
Wires: Wires{},
|
||||
Networks: Networks{},
|
||||
Guests: Guests{},
|
||||
Hosts: Hosts{},
|
||||
SecurityGroups: SecurityGroups{},
|
||||
SecurityGroupRules: SecurityGroupRules{},
|
||||
Guestnetworks: Guestnetworks{},
|
||||
Guestsecgroups: Guestsecgroups{},
|
||||
Elasticips: Elasticips{},
|
||||
NetworkAddresses: NetworkAddresses{},
|
||||
Vpcs: Vpcs{},
|
||||
Wires: Wires{},
|
||||
Networks: Networks{},
|
||||
Guests: Guests{},
|
||||
Hosts: Hosts{},
|
||||
SecurityGroups: SecurityGroups{},
|
||||
SecurityGroupRules: SecurityGroupRules{},
|
||||
Guestnetworks: Guestnetworks{},
|
||||
Guestsecgroups: Guestsecgroups{},
|
||||
Elasticips: Elasticips{},
|
||||
NetworkAddresses: NetworkAddresses{},
|
||||
Guestnetworksecgroups: Guestnetworksecgroups{},
|
||||
|
||||
DnsZones: DnsZones{},
|
||||
DnsRecords: DnsRecords{},
|
||||
@@ -150,6 +154,7 @@ func (mss *ModelSets) ModelSetList() []apihelper.IModelSet {
|
||||
mss.Guestsecgroups,
|
||||
mss.Elasticips,
|
||||
mss.NetworkAddresses,
|
||||
mss.Guestnetworksecgroups,
|
||||
|
||||
mss.DnsZones,
|
||||
mss.DnsRecords,
|
||||
@@ -172,17 +177,18 @@ func (mss *ModelSets) NewEmpty() apihelper.IModelSets {
|
||||
|
||||
func (mss *ModelSets) copy_() *ModelSets {
|
||||
mssCopy := &ModelSets{
|
||||
Vpcs: mss.Vpcs.Copy().(Vpcs),
|
||||
Wires: mss.Wires.Copy().(Wires),
|
||||
Networks: mss.Networks.Copy().(Networks),
|
||||
Guests: mss.Guests.Copy().(Guests),
|
||||
Hosts: mss.Hosts.Copy().(Hosts),
|
||||
SecurityGroups: mss.SecurityGroups.Copy().(SecurityGroups),
|
||||
SecurityGroupRules: mss.SecurityGroupRules.Copy().(SecurityGroupRules),
|
||||
Guestnetworks: mss.Guestnetworks.Copy().(Guestnetworks),
|
||||
Guestsecgroups: mss.Guestsecgroups.Copy().(Guestsecgroups),
|
||||
Elasticips: mss.Elasticips.Copy().(Elasticips),
|
||||
NetworkAddresses: mss.NetworkAddresses.Copy().(NetworkAddresses),
|
||||
Vpcs: mss.Vpcs.Copy().(Vpcs),
|
||||
Wires: mss.Wires.Copy().(Wires),
|
||||
Networks: mss.Networks.Copy().(Networks),
|
||||
Guests: mss.Guests.Copy().(Guests),
|
||||
Hosts: mss.Hosts.Copy().(Hosts),
|
||||
SecurityGroups: mss.SecurityGroups.Copy().(SecurityGroups),
|
||||
SecurityGroupRules: mss.SecurityGroupRules.Copy().(SecurityGroupRules),
|
||||
Guestnetworks: mss.Guestnetworks.Copy().(Guestnetworks),
|
||||
Guestsecgroups: mss.Guestsecgroups.Copy().(Guestsecgroups),
|
||||
Elasticips: mss.Elasticips.Copy().(Elasticips),
|
||||
NetworkAddresses: mss.NetworkAddresses.Copy().(NetworkAddresses),
|
||||
Guestnetworksecgroups: mss.Guestnetworksecgroups.Copy().(Guestnetworksecgroups),
|
||||
|
||||
DnsZones: mss.DnsZones.Copy().(DnsZones),
|
||||
DnsRecords: mss.DnsRecords.Copy().(DnsRecords),
|
||||
@@ -273,12 +279,16 @@ func (mss *ModelSets) join() bool {
|
||||
msg = append(msg, "mss.SecurityGroups.joinSecurityGroupRules(mss.SecurityGroupRules)")
|
||||
p = append(p, mss.Guestsecgroups.join(mss.SecurityGroups, mss.Guests))
|
||||
msg = append(msg, "mss.Guestsecgroups.join(mss.SecurityGroups, mss.Guests)")
|
||||
p = append(p, mss.Guestnetworksecgroups.joinSecurityGroups(mss.SecurityGroups))
|
||||
msg = append(msg, "mss.Guestnetworksecgroups.joinSecurityGroups(mss.SecurityGroups)")
|
||||
p = append(p, mss.Guestnetworks.joinGuests(mss.Guests))
|
||||
msg = append(msg, "mss.Guestnetworks.joinGuests(mss.Guests)")
|
||||
p = append(p, mss.Guestnetworks.joinElasticips(mss.Elasticips))
|
||||
msg = append(msg, "mss.Guestnetworks.joinElasticips(mss.Elasticips)")
|
||||
p = append(p, mss.Guestnetworks.joinNetworkAddresses(mss.NetworkAddresses))
|
||||
msg = append(msg, "mss.Guestnetworks.joinNetworkAddresses(mss.NetworkAddresses)")
|
||||
p = append(p, mss.Guestnetworks.joinGuestnetworksecgroups(mss.Guestnetworksecgroups))
|
||||
msg = append(msg, "mss.Guestnetworks.joinGuestnetworksecgroups(mss.Guestnetworksecgroups)")
|
||||
p = append(p, mss.Groups.joinGroupnetworks(mss.Groupnetworks, mss.Networks))
|
||||
msg = append(msg, "mss.Groups.joinGroupnetworks(mss.Groupnetworks, mss.Networks)")
|
||||
p = append(p, mss.Groupnetworks.joinElasticips(mss.Elasticips))
|
||||
|
||||
@@ -53,6 +53,37 @@ func (el *Guest) OrderedSecurityGroupRules() []*SecurityGroupRule {
|
||||
return rs
|
||||
}
|
||||
|
||||
func (el *Guestnetwork) OrderedSecurityGroupRules(guest *Guest) []*SecurityGroupRule {
|
||||
if len(el.Guestnetworksecgroups) == 0 {
|
||||
return guest.OrderedSecurityGroupRules()
|
||||
}
|
||||
// deny any incoming traffic and allow ARP
|
||||
rs := []*SecurityGroupRule{
|
||||
{
|
||||
// deny all in-bound traffic
|
||||
SSecurityGroupRule: compute_models.SSecurityGroupRule{
|
||||
Priority: 1,
|
||||
Direction: string(secrules.SecurityRuleIngress),
|
||||
Action: string(secrules.SecurityRuleDeny),
|
||||
},
|
||||
},
|
||||
{
|
||||
// allow in-bound arp traffic
|
||||
SSecurityGroupRule: compute_models.SSecurityGroupRule{
|
||||
Priority: 2,
|
||||
Direction: string(secrules.SecurityRuleIngress),
|
||||
Protocol: "arp",
|
||||
Action: string(secrules.SecurityRuleAllow),
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, guestSecgroup := range el.Guestnetworksecgroups {
|
||||
rs = append(rs, guestSecgroup.SecurityGroup.securityGroupRules(100)...)
|
||||
}
|
||||
sort.Slice(rs, SecurityGroupRuleLessFunc(rs))
|
||||
return rs
|
||||
}
|
||||
|
||||
func (el *SecurityGroup) securityGroupRules(basePriority int64) []*SecurityGroupRule {
|
||||
rs := make([]*SecurityGroupRule, 0, len(el.SecurityGroupRules))
|
||||
for _, r := range el.SecurityGroupRules {
|
||||
|
||||
@@ -822,7 +822,7 @@ func (keeper *OVNNorthboundKeeper) ClaimGuestnetwork(ctx context.Context, guestn
|
||||
if len(guestnetwork.Ip6Addr) > 0 {
|
||||
enableIPv6 = true
|
||||
}
|
||||
sgrs := guest.OrderedSecurityGroupRules()
|
||||
sgrs := guestnetwork.OrderedSecurityGroupRules(guest)
|
||||
for _, sgr := range sgrs {
|
||||
// kvm not support peer secgroup
|
||||
acl, err := ruleToAcl(lportName, sgr, enableIPv6)
|
||||
|
||||
Reference in New Issue
Block a user