mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-10-24 02:26:39 +08:00
add: 支持创建安全组时同时创建规则
This commit is contained in:
@@ -9,6 +9,58 @@ SecgroupCreate:
|
||||
type: string
|
||||
example: secgrou-description
|
||||
description: 安全组描述
|
||||
rules:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/SecgroupRuleCreate'
|
||||
|
||||
SecgroupRuleCreate:
|
||||
type: object
|
||||
properties:
|
||||
priority:
|
||||
type: integer
|
||||
example: 34
|
||||
default: 1
|
||||
description: 安全组优先级,数字越高,优先级越高 范围 1-100
|
||||
protocol:
|
||||
type: string
|
||||
example: icmp
|
||||
enum: [icmp, tcp, udp, any]
|
||||
requried: true
|
||||
description: 协议
|
||||
ports:
|
||||
type: string
|
||||
example: 10-200
|
||||
description: 端口或端口范围
|
||||
direction:
|
||||
type: string
|
||||
example: in
|
||||
enum: [in, out]
|
||||
requried: true
|
||||
description: 规则出入方向
|
||||
cidr:
|
||||
type: string
|
||||
example: 0.0.0.0/0
|
||||
default: "0.0.0.0/0"
|
||||
description: IP地址或网络地址
|
||||
action:
|
||||
type: string
|
||||
example: allow
|
||||
enum: [allow, deny]
|
||||
requried: true
|
||||
description: 允许或拒绝
|
||||
port_start:
|
||||
type: integer
|
||||
example: 10
|
||||
description: 和port_end参数配合使用,若指定ports则此参数失效
|
||||
port_end:
|
||||
type: integer
|
||||
example: 100
|
||||
description: 和port_start参数配合使用,若指定ports则此参数失效
|
||||
description:
|
||||
type: string
|
||||
example: test-description
|
||||
description: 规则描述信息
|
||||
|
||||
SecgroupResponse:
|
||||
type: object
|
||||
@@ -103,4 +155,4 @@ SecgroupAddRule:
|
||||
description:
|
||||
type: string
|
||||
example: test-rule
|
||||
description: 规则描述
|
||||
description: 规则描述
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
package compute
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
"yunion.io/x/onecloud/pkg/apis"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
)
|
||||
|
||||
type SSecgroupRuleCreateInput struct {
|
||||
apis.Meta
|
||||
|
||||
Priority int
|
||||
Protocol string
|
||||
Ports string
|
||||
PortStart int
|
||||
PortEnd int
|
||||
Direction string
|
||||
CIDR string
|
||||
Action string
|
||||
Description string
|
||||
SecgroupId string
|
||||
}
|
||||
|
||||
func (input *SSecgroupRuleCreateInput) Check() error {
|
||||
rule := secrules.SecurityRule{
|
||||
Priority: input.Priority,
|
||||
Direction: secrules.TSecurityRuleDirection(input.Direction),
|
||||
Action: secrules.TSecurityRuleAction(input.Action),
|
||||
Protocol: input.Protocol,
|
||||
PortStart: input.PortStart,
|
||||
PortEnd: input.PortEnd,
|
||||
Ports: []int{},
|
||||
}
|
||||
|
||||
if len(input.Ports) > 0 {
|
||||
err := rule.ParsePorts(input.Ports)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "ParsePorts(%s)", input.Ports)
|
||||
}
|
||||
}
|
||||
|
||||
if len(input.CIDR) > 0 {
|
||||
if !regutils.MatchCIDR(input.CIDR) && !regutils.MatchIPAddr(input.CIDR) {
|
||||
return fmt.Errorf("invalid ip address: %s", input.CIDR)
|
||||
}
|
||||
} else {
|
||||
input.CIDR = "0.0.0.0/0"
|
||||
}
|
||||
|
||||
if rule.PortStart > 0 && rule.PortEnd > 0 {
|
||||
if rule.PortStart != rule.PortEnd {
|
||||
input.Ports = fmt.Sprintf("%d-%d", rule.PortStart, rule.PortEnd)
|
||||
} else {
|
||||
input.Ports = fmt.Sprintf("%d", input.PortStart)
|
||||
}
|
||||
}
|
||||
|
||||
return rule.ValidateRule()
|
||||
}
|
||||
|
||||
type SSecgroupCreateInput struct {
|
||||
apis.Meta
|
||||
|
||||
Name string
|
||||
Description string
|
||||
Rules []SSecgroupRuleCreateInput
|
||||
}
|
||||
@@ -23,13 +23,14 @@ import (
|
||||
"yunion.io/x/jsonutils"
|
||||
"yunion.io/x/log"
|
||||
"yunion.io/x/pkg/util/compare"
|
||||
"yunion.io/x/pkg/util/regutils"
|
||||
"yunion.io/x/pkg/util/secrules"
|
||||
"yunion.io/x/pkg/util/stringutils"
|
||||
"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/db/lockman"
|
||||
"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/rbacutils"
|
||||
@@ -148,47 +149,29 @@ func (self *SSecurityGroupRule) BeforeInsert() {
|
||||
}
|
||||
|
||||
func (manager *SSecurityGroupRuleManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
defsecgroup, _ := data.GetString("secgroup")
|
||||
if len(defsecgroup) == 0 {
|
||||
return nil, httperrors.NewMissingParameterError("secgroup")
|
||||
}
|
||||
secgroup, _ := SecurityGroupManager.FetchByIdOrName(userCred, defsecgroup)
|
||||
if secgroup == nil {
|
||||
return nil, httperrors.NewInputParameterError("Security Group %s not found", defsecgroup)
|
||||
}
|
||||
data.Add(jsonutils.NewString(secgroup.GetId()), "secgroup_id")
|
||||
|
||||
priority, _ := data.Int("priority")
|
||||
direction, _ := data.GetString("direction")
|
||||
action, _ := data.GetString("action")
|
||||
cidr, _ := data.GetString("cidr")
|
||||
protocol, _ := data.GetString("protocol")
|
||||
|
||||
if len(cidr) > 0 {
|
||||
if !regutils.MatchCIDR(cidr) && !regutils.MatchIPAddr(cidr) {
|
||||
return nil, httperrors.NewInputParameterError("invalid ip address: %s", cidr)
|
||||
}
|
||||
} else {
|
||||
data.Add(jsonutils.NewString("0.0.0.0/0"), "cidr")
|
||||
secgroupV := validators.NewModelIdOrNameValidator("secgroup", "secgroup", ownerId)
|
||||
err := secgroupV.Validate(data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
rule := secrules.SecurityRule{
|
||||
Priority: int(priority),
|
||||
Direction: secrules.TSecurityRuleDirection(direction),
|
||||
Action: secrules.TSecurityRuleAction(action),
|
||||
Protocol: protocol,
|
||||
Ports: []int{},
|
||||
PortStart: -1,
|
||||
PortEnd: -1,
|
||||
input := &api.SSecgroupRuleCreateInput{}
|
||||
err = data.Unmarshal(input)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Failed to unmarshal input: %v", err)
|
||||
}
|
||||
ports, _ := data.GetString("ports")
|
||||
if err := rule.ParsePorts(ports); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
|
||||
err = input.Check()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if err := rule.ValidateRule(); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
|
||||
data, err = manager.SResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return manager.SResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data)
|
||||
return input.JSON(input), nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroupRule) ValidateUpdateData(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
|
||||
|
||||
@@ -231,7 +231,49 @@ func (manager *SSecurityGroupManager) ValidateCreateData(
|
||||
data *jsonutils.JSONDict,
|
||||
) (*jsonutils.JSONDict, error) {
|
||||
// TODO: check set pending quota
|
||||
return manager.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data)
|
||||
|
||||
input := &api.SSecgroupCreateInput{}
|
||||
|
||||
err := data.Unmarshal(input)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("Failed to unmarshal input: %v", err)
|
||||
}
|
||||
|
||||
for i, rule := range input.Rules {
|
||||
err = rule.Check()
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("rule %d is invalid: %s", i, err)
|
||||
}
|
||||
}
|
||||
|
||||
data, err = manager.SSharableVirtualResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, data)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return input.JSON(input), nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
|
||||
self.SSharableVirtualResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
|
||||
|
||||
input := &api.SSecgroupCreateInput{}
|
||||
data.Unmarshal(input)
|
||||
|
||||
for _, r := range input.Rules {
|
||||
rule := &SSecurityGroupRule{
|
||||
Priority: int64(r.Priority),
|
||||
Protocol: r.Protocol,
|
||||
Ports: r.Ports,
|
||||
Direction: r.Direction,
|
||||
CIDR: r.CIDR,
|
||||
Action: r.Action,
|
||||
Description: r.Description,
|
||||
SecgroupID: self.Id,
|
||||
}
|
||||
|
||||
SecurityGroupRuleManager.TableSpec().Insert(rule)
|
||||
}
|
||||
}
|
||||
|
||||
func (manager *SSecurityGroupManager) FetchSecgroupById(secId string) *SSecurityGroup {
|
||||
|
||||
Reference in New Issue
Block a user