mirror of
https://github.com/yunionio/cloudpods.git
synced 2026-05-06 21:52:54 +08:00
支持批量添加安全组规则
This commit is contained in:
@@ -99,6 +99,7 @@ func init() {
|
||||
Name string `help:"Name of security group to update"`
|
||||
Desc string `help:"Description of security groups"`
|
||||
}
|
||||
|
||||
R(&SecGroupsUpdateOptions{}, "secgroup-update", "Update details of a security group", func(s *mcclient.ClientSession, args *SecGroupsUpdateOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if len(args.Name) > 0 {
|
||||
@@ -114,53 +115,25 @@ func init() {
|
||||
printObject(secgroups)
|
||||
return nil
|
||||
})
|
||||
type SecGroupsUpdateRulesOptions struct {
|
||||
ID string `help:"ID or Name of security group"`
|
||||
RULES []string `help:"security rule to create"`
|
||||
|
||||
type SecGroupsAddRuleOptions struct {
|
||||
ID string `help:"ID or Name of security group"`
|
||||
DIRECTION string `help:"Direction of rule" choices:"in|out"`
|
||||
PROTOCOL string `help:"Protocol of rule" choices:"any|tcp|udp|icmp"`
|
||||
ACTION string `help:"Actin of rule" choices:"allow|deny"`
|
||||
PRIORITY int `help:"Priority for rule, range 1 ~ 100"`
|
||||
Cidr string `help:"IP or CIRD for rule"`
|
||||
Description string `help:"Desciption for rule"`
|
||||
Ports string `help:"Port for rule"`
|
||||
}
|
||||
|
||||
R(&SecGroupsUpdateRulesOptions{}, "secgroup-add-rules", "Add security rules to a security group", func(s *mcclient.ClientSession, args *SecGroupsUpdateRulesOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if len(args.RULES) > 0 {
|
||||
for i, a := range args.RULES {
|
||||
params.Add(jsonutils.NewString(a), fmt.Sprintf("rule.%d", i))
|
||||
}
|
||||
}
|
||||
result, err := modules.SecGroups.PerformAction(s, args.ID, "add-rules", params)
|
||||
R(&SecGroupsAddRuleOptions{}, "secgroup-add-rule", "Add rule for a security group", func(s *mcclient.ClientSession, args *SecGroupsAddRuleOptions) error {
|
||||
params, err := options.StructToParams(args)
|
||||
secgroups, err := modules.SecGroups.PerformAction(s, args.ID, "add-rule", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&SecGroupsUpdateRulesOptions{}, "secgroup-remove-rules", "Remove security rules from a security group", func(s *mcclient.ClientSession, args *SecGroupsUpdateRulesOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if len(args.RULES) > 0 {
|
||||
for i, a := range args.RULES {
|
||||
params.Add(jsonutils.NewString(a), fmt.Sprintf("rule.%d", i))
|
||||
}
|
||||
}
|
||||
result, err := modules.SecGroups.PerformAction(s, args.ID, "remove-rules", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
return nil
|
||||
})
|
||||
|
||||
R(&SecGroupsUpdateRulesOptions{}, "secgroup-set-rules", "Set security rules from a security group", func(s *mcclient.ClientSession, args *SecGroupsUpdateRulesOptions) error {
|
||||
params := jsonutils.NewDict()
|
||||
if len(args.RULES) > 0 {
|
||||
for i, a := range args.RULES {
|
||||
params.Add(jsonutils.NewString(a), fmt.Sprintf("rule.%d", i))
|
||||
}
|
||||
}
|
||||
result, err := modules.SecGroups.PerformAction(s, args.ID, "set-rules", params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
printObject(result)
|
||||
printObject(secgroups)
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -166,40 +166,10 @@ func (manager *SSecurityGroupRuleManager) ValidateCreateData(ctx context.Context
|
||||
PortEnd: -1,
|
||||
}
|
||||
ports, _ := data.GetString("ports")
|
||||
var err error
|
||||
if len(ports) > 0 {
|
||||
if strings.Index(ports, "-") > 0 {
|
||||
portsInfo := strings.Split(ports, "-")
|
||||
if len(portsInfo) != 2 {
|
||||
return nil, httperrors.NewInputParameterError("invalid ports: %s", ports)
|
||||
}
|
||||
rule.PortStart, err = strconv.Atoi(portsInfo[0])
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid port start: %s", portsInfo[0])
|
||||
}
|
||||
rule.PortEnd, err = strconv.Atoi(portsInfo[1])
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid port end: %s", portsInfo[1])
|
||||
}
|
||||
} else if strings.Index(ports, ",") > 0 {
|
||||
for _, port := range strings.Split(ports, ",") {
|
||||
_port, err := strconv.Atoi(port)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid port : %d", port)
|
||||
}
|
||||
rule.Ports = append(rule.Ports, _port)
|
||||
}
|
||||
} else {
|
||||
port, err := strconv.Atoi(ports)
|
||||
if err != nil {
|
||||
return nil, httperrors.NewInputParameterError("invalid ports: %s", ports)
|
||||
}
|
||||
rule.Ports = append(rule.Ports, port)
|
||||
}
|
||||
if err := rule.ParsePorts(ports); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
|
||||
err = rule.ValidateRule()
|
||||
if err != nil {
|
||||
if err := rule.ValidateRule(); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
return manager.SResourceBaseManager.ValidateCreateData(ctx, userCred, ownerProjId, query, data)
|
||||
|
||||
@@ -9,6 +9,7 @@ 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/utils"
|
||||
"yunion.io/x/sqlchemy"
|
||||
@@ -166,6 +167,49 @@ func totalSecurityGroupCount(projectId string) int {
|
||||
return q.Count()
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) AllowPerformAddRule(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return self.IsOwner(userCred) || db.IsAdminAllowPerform(userCred, self, "add-rule")
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) PerformAddRule(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) (jsonutils.JSONObject, error) {
|
||||
secgrouprule := &SSecurityGroupRule{SecgroupID: self.Id}
|
||||
secgrouprule.SetModelManager(SecurityGroupRuleManager)
|
||||
secgrouprule.Direction, _ = data.GetString("direction")
|
||||
secgrouprule.Action, _ = data.GetString("action")
|
||||
secgrouprule.Priority, _ = data.Int("priority")
|
||||
secgrouprule.Description, _ = data.GetString("description")
|
||||
secgrouprule.Protocol, _ = data.GetString("protocol")
|
||||
secgrouprule.CIDR, _ = data.GetString("cidr")
|
||||
if len(secgrouprule.CIDR) > 0 {
|
||||
if !regutils.MatchCIDR(secgrouprule.CIDR) && !regutils.MatchIPAddr(secgrouprule.CIDR) {
|
||||
return nil, httperrors.NewInputParameterError("invalid ip address: %s", secgrouprule.CIDR)
|
||||
}
|
||||
} else {
|
||||
secgrouprule.CIDR = "0.0.0.0/0"
|
||||
}
|
||||
rule := secrules.SecurityRule{
|
||||
Priority: int(secgrouprule.Priority),
|
||||
Direction: secrules.TSecurityRuleDirection(secgrouprule.Direction),
|
||||
Action: secrules.TSecurityRuleAction(secgrouprule.Action),
|
||||
Protocol: secgrouprule.Protocol,
|
||||
Ports: []int{},
|
||||
PortStart: -1,
|
||||
PortEnd: -1,
|
||||
}
|
||||
ports, _ := data.GetString("ports")
|
||||
if err := rule.ParsePorts(ports); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
if err := rule.ValidateRule(); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
if err := SecurityGroupRuleManager.TableSpec().Insert(secgrouprule); err != nil {
|
||||
return nil, httperrors.NewInputParameterError(err.Error())
|
||||
}
|
||||
self.DoSync(ctx, userCred)
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (self *SSecurityGroup) AllowPerformClone(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
81
vendor/yunion.io/x/pkg/util/secrules/secrules.go
generated
vendored
81
vendor/yunion.io/x/pkg/util/secrules/secrules.go
generated
vendored
@@ -149,42 +149,11 @@ func ParseSecurityRule(pattern string) (*SecurityRule, error) {
|
||||
}
|
||||
rule.Protocol = seg
|
||||
} else if status == SEG_PORT {
|
||||
if len(seg) == 0 {
|
||||
status = SEG_END
|
||||
} else if idx := strings.Index(seg, "-"); idx > -1 {
|
||||
segs := strings.SplitN(seg, "-", 2)
|
||||
var ps, pe int
|
||||
var err error
|
||||
if ps, err = parsePortString(segs[0]); err != nil {
|
||||
return nil, ErrInvalidPortRange
|
||||
}
|
||||
if pe, err = parsePortString(segs[1]); err != nil {
|
||||
return nil, ErrInvalidPortRange
|
||||
}
|
||||
if ps > pe {
|
||||
ps, pe = pe, ps
|
||||
}
|
||||
rule.PortStart = ps
|
||||
rule.PortEnd = pe
|
||||
} else if idx := strings.Index(seg, ","); idx > -1 {
|
||||
ports := make([]int, 0)
|
||||
segs := strings.Split(seg, ",")
|
||||
for _, seg := range segs {
|
||||
p, err := parsePortString(seg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
ports = append(ports, p)
|
||||
}
|
||||
rule.Ports = ports
|
||||
} else {
|
||||
p, err := parsePortString(seg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rule.PortStart, rule.PortEnd = p, p
|
||||
}
|
||||
status = SEG_END
|
||||
if err := rule.ParsePorts(seg); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return rule, nil
|
||||
}
|
||||
}
|
||||
return rule, nil
|
||||
@@ -198,6 +167,48 @@ func (rule *SecurityRule) IsWildMatch() bool {
|
||||
rule.PortEnd == 0
|
||||
}
|
||||
|
||||
func (rule *SecurityRule) ParsePorts(seg string) error {
|
||||
if len(seg) == 0 {
|
||||
rule.Ports = []int{}
|
||||
rule.PortStart = -1
|
||||
rule.PortEnd = -1
|
||||
return nil
|
||||
} else if idx := strings.Index(seg, "-"); idx > -1 {
|
||||
segs := strings.SplitN(seg, "-", 2)
|
||||
var ps, pe int
|
||||
var err error
|
||||
if ps, err = parsePortString(segs[0]); err != nil {
|
||||
return ErrInvalidPortRange
|
||||
}
|
||||
if pe, err = parsePortString(segs[1]); err != nil {
|
||||
return ErrInvalidPortRange
|
||||
}
|
||||
if ps > pe {
|
||||
ps, pe = pe, ps
|
||||
}
|
||||
rule.PortStart = ps
|
||||
rule.PortEnd = pe
|
||||
} else if idx := strings.Index(seg, ","); idx > -1 {
|
||||
ports := make([]int, 0)
|
||||
segs := strings.Split(seg, ",")
|
||||
for _, seg := range segs {
|
||||
p, err := parsePortString(seg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ports = append(ports, p)
|
||||
}
|
||||
rule.Ports = ports
|
||||
} else {
|
||||
p, err := parsePortString(seg)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
rule.PortStart, rule.PortEnd = p, p
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (rule *SecurityRule) ValidateRule() error {
|
||||
if !utils.IsInStringArray(string(rule.Direction), []string{string(DIR_IN), string(DIR_OUT)}) {
|
||||
return ErrInvalidDirection
|
||||
|
||||
Reference in New Issue
Block a user