Files
cloudpods/pkg/util/openstack/securitygroup.go
2019-01-02 17:38:59 +08:00

186 lines
4.8 KiB
Go

package openstack
import (
"net"
"strings"
"time"
"yunion.io/x/jsonutils"
"yunion.io/x/onecloud/pkg/cloudprovider"
"yunion.io/x/pkg/util/secrules"
"yunion.io/x/pkg/utils"
)
type SSecurityGroupRule struct {
Direction string
Ethertype string
ID string
PortRangeMax int
PortRangeMin int
Protocol string
RemoteGroupID string
RemoteIpPrefix string
SecurityGroupID string
ProjectID string
RevisionNumber int
Tags []string
TenantID string
CreatedAt time.Time
UpdatedAt time.Time
Description string
}
type SSecurityGroup struct {
vpc *SVpc
Description string
ID string
Name string
SecurityGroupRules []SSecurityGroupRule
ProjectID string
RevisionNumber int
CreatedAt time.Time
UpdatedAt time.Time
Tags []string
TenantID string
}
func (region *SRegion) GetSecurityGroup(secgroupId string) (*SSecurityGroup, error) {
_, resp, err := region.Get("network", "/v2.0/security-groups/"+secgroupId, "", nil)
if err != nil {
return nil, err
}
secgroup := &SSecurityGroup{}
return secgroup, resp.Unmarshal(secgroup, "security_group")
}
func (region *SRegion) GetSecurityGroups() ([]SSecurityGroup, error) {
_, resp, err := region.Get("network", "/v2.0/security-groups", "", nil)
if err != nil {
return nil, err
}
secgroups := []SSecurityGroup{}
return secgroups, resp.Unmarshal(&secgroups, "security_groups")
}
func (secgroup *SSecurityGroup) GetMetadata() *jsonutils.JSONDict {
return nil
}
func (secgroup *SSecurityGroup) GetVpcId() string {
return "normal"
}
func (secgroup *SSecurityGroup) GetId() string {
return secgroup.ID
}
func (secgroup *SSecurityGroup) GetGlobalId() string {
return secgroup.ID
}
func (secgroup *SSecurityGroup) GetDescription() string {
return secgroup.Description
}
func (secgroup *SSecurityGroup) GetName() string {
if len(secgroup.Name) > 0 {
return secgroup.Name
}
return secgroup.ID
}
func (secgroup *SSecurityGroupRule) String() string {
rules := secgroup.toRules()
result := []string{}
for _, rule := range rules {
result = append(result, rule.String())
}
return strings.Join(result, ";")
}
func (secgrouprule *SSecurityGroupRule) toRules() []secrules.SecurityRule {
rules := []secrules.SecurityRule{}
// 暂时忽略IPv6安全组规则,忽略远端也是安全组的规则
if secgrouprule.Ethertype != "IPv4" || len(secgrouprule.RemoteGroupID) > 0 {
return rules
}
rule := secrules.SecurityRule{
Direction: secrules.DIR_IN,
Action: secrules.SecurityRuleAllow,
Description: secgrouprule.Description,
Priority: 1,
}
if utils.IsInStringArray(secgrouprule.Protocol, []string{"", "0", "any"}) {
rule.Protocol = secrules.PROTO_ANY
} else if utils.IsInStringArray(secgrouprule.Protocol, []string{"6", "tcp"}) {
rule.Protocol = secrules.PROTO_TCP
} else if utils.IsInStringArray(secgrouprule.Protocol, []string{"17", "udp"}) {
rule.Protocol = secrules.PROTO_UDP
} else if utils.IsInStringArray(secgrouprule.Protocol, []string{"1", "icmp"}) {
rule.Protocol = secrules.PROTO_ICMP
} else {
return rules
}
if secgrouprule.Direction == "egress" {
rule.Direction = secrules.DIR_OUT
}
if len(secgrouprule.RemoteIpPrefix) == 0 {
secgrouprule.RemoteIpPrefix = "0.0.0.0/0"
}
_, ipnet, err := net.ParseCIDR(secgrouprule.RemoteIpPrefix)
if err != nil {
return rules
}
rule.IPNet = ipnet
if secgrouprule.PortRangeMax > 0 && secgrouprule.PortRangeMin > 0 {
if secgrouprule.PortRangeMax == secgrouprule.PortRangeMin {
rule.Ports = []int{secgrouprule.PortRangeMax}
} else {
rule.PortStart = secgrouprule.PortRangeMin
rule.PortEnd = secgrouprule.PortRangeMax
}
}
if err := rule.ValidateRule(); err != nil {
return rules
}
return []secrules.SecurityRule{rule}
}
func (secgroup *SSecurityGroup) GetRules() ([]secrules.SecurityRule, error) {
rules := []secrules.SecurityRule{}
for _, rule := range secgroup.SecurityGroupRules {
subRules := rule.toRules()
rules = append(rules, subRules...)
}
return rules, nil
}
func (secgroup *SSecurityGroup) GetStatus() string {
return ""
}
func (secgroup *SSecurityGroup) IsEmulated() bool {
return false
}
func (secgroup *SSecurityGroup) Refresh() error {
new, err := secgroup.vpc.region.GetSecurityGroup(secgroup.ID)
if err != nil {
return err
}
return jsonutils.Update(secgroup, new)
}
func (secgroup *SRegion) SyncSecurityGroup(secgroupId string, vpcId string, name string, desc string, rules []secrules.SecurityRule) (string, error) {
return "", cloudprovider.ErrNotImplemented
}
func (region *SRegion) DeleteSecurityGroup(vpcId, secGroupId string) error {
return cloudprovider.ErrNotImplemented
}
func (region *SRegion) CreateSecurityGroup(name, description string) (*SSecurityGroup, error) {
return nil, cloudprovider.ErrNotImplemented
}