2018-02-12 17:10:05 +00:00
|
|
|
package egoscale
|
|
|
|
|
|
|
|
import (
|
2018-09-14 08:06:03 +00:00
|
|
|
"context"
|
|
|
|
"fmt"
|
2018-02-12 17:10:05 +00:00
|
|
|
"net/url"
|
|
|
|
"strconv"
|
2018-09-14 08:06:03 +00:00
|
|
|
"strings"
|
2018-02-12 17:10:05 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
// SecurityGroup represent a firewalling set of rules
|
|
|
|
type SecurityGroup struct {
|
2018-09-14 08:06:03 +00:00
|
|
|
Account string `json:"account,omitempty" doc:"the account owning the security group"`
|
|
|
|
Description string `json:"description,omitempty" doc:"the description of the security group"`
|
|
|
|
EgressRule []EgressRule `json:"egressrule,omitempty" doc:"the list of egress rules associated with the security group"`
|
2019-03-14 10:04:04 +00:00
|
|
|
ID *UUID `json:"id" doc:"the ID of the security group"`
|
2018-09-14 08:06:03 +00:00
|
|
|
IngressRule []IngressRule `json:"ingressrule,omitempty" doc:"the list of ingress rules associated with the security group"`
|
|
|
|
Name string `json:"name,omitempty" doc:"the name of the security group"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 08:06:03 +00:00
|
|
|
// UserSecurityGroup converts a SecurityGroup to a UserSecurityGroup
|
|
|
|
func (sg SecurityGroup) UserSecurityGroup() UserSecurityGroup {
|
|
|
|
return UserSecurityGroup{
|
2019-03-14 10:04:04 +00:00
|
|
|
Group: sg.Name,
|
2018-09-14 08:06:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// ListRequest builds the ListSecurityGroups request
|
|
|
|
func (sg SecurityGroup) ListRequest() (ListCommand, error) {
|
|
|
|
req := &ListSecurityGroups{
|
|
|
|
ID: sg.ID,
|
|
|
|
SecurityGroupName: sg.Name,
|
|
|
|
}
|
|
|
|
|
|
|
|
return req, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// Delete deletes the given Security Group
|
|
|
|
func (sg SecurityGroup) Delete(ctx context.Context, client *Client) error {
|
|
|
|
if sg.ID == nil && sg.Name == "" {
|
|
|
|
return fmt.Errorf("a SecurityGroup may only be deleted using ID or Name")
|
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
req := &DeleteSecurityGroup{}
|
2018-09-14 08:06:03 +00:00
|
|
|
|
|
|
|
if sg.ID != nil {
|
|
|
|
req.ID = sg.ID
|
|
|
|
} else {
|
|
|
|
req.Name = sg.Name
|
|
|
|
}
|
|
|
|
|
|
|
|
return client.BooleanRequestWithContext(ctx, req)
|
|
|
|
}
|
|
|
|
|
|
|
|
// RuleByID returns IngressRule or EgressRule by a rule ID
|
|
|
|
func (sg SecurityGroup) RuleByID(ruleID UUID) (*IngressRule, *EgressRule) {
|
|
|
|
for i, in := range sg.IngressRule {
|
|
|
|
if in.RuleID.Equal(ruleID) {
|
|
|
|
return &sg.IngressRule[i], nil
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for i, out := range sg.EgressRule {
|
|
|
|
if out.RuleID.Equal(ruleID) {
|
|
|
|
return nil, &sg.EgressRule[i]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
2018-02-12 17:10:05 +00:00
|
|
|
// IngressRule represents the ingress rule
|
|
|
|
type IngressRule struct {
|
2019-03-14 10:04:04 +00:00
|
|
|
CIDR *CIDR `json:"cidr,omitempty" doc:"the CIDR notation for the base IP address of the security group rule"`
|
|
|
|
Description string `json:"description,omitempty" doc:"description of the security group rule"`
|
|
|
|
EndPort uint16 `json:"endport,omitempty" doc:"the ending port of the security group rule "`
|
|
|
|
IcmpCode uint8 `json:"icmpcode,omitempty" doc:"the code for the ICMP message response"`
|
|
|
|
IcmpType uint8 `json:"icmptype,omitempty" doc:"the type of the ICMP message response"`
|
|
|
|
Protocol string `json:"protocol,omitempty" doc:"the protocol of the security group rule"`
|
|
|
|
RuleID *UUID `json:"ruleid" doc:"the id of the security group rule"`
|
|
|
|
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"security group name"`
|
|
|
|
StartPort uint16 `json:"startport,omitempty" doc:"the starting port of the security group rule"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// EgressRule represents the ingress rule
|
|
|
|
type EgressRule IngressRule
|
|
|
|
|
|
|
|
// UserSecurityGroup represents the traffic of another security group
|
|
|
|
type UserSecurityGroup struct {
|
2019-03-14 10:04:04 +00:00
|
|
|
Group string `json:"group,omitempty"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 08:06:03 +00:00
|
|
|
// String gives the UserSecurityGroup name
|
|
|
|
func (usg UserSecurityGroup) String() string {
|
|
|
|
return usg.Group
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// CreateSecurityGroup represents a security group creation
|
|
|
|
type CreateSecurityGroup struct {
|
2018-09-14 08:06:03 +00:00
|
|
|
Name string `json:"name" doc:"name of the security group"`
|
|
|
|
Description string `json:"description,omitempty" doc:"the description of the security group"`
|
|
|
|
_ bool `name:"createSecurityGroup" description:"Creates a security group"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// Response returns the struct to unmarshal
|
|
|
|
func (CreateSecurityGroup) Response() interface{} {
|
2018-09-14 08:06:03 +00:00
|
|
|
return new(SecurityGroup)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// DeleteSecurityGroup represents a security group deletion
|
|
|
|
type DeleteSecurityGroup struct {
|
2019-03-14 10:04:04 +00:00
|
|
|
ID *UUID `json:"id,omitempty" doc:"The ID of the security group. Mutually exclusive with name parameter"`
|
|
|
|
Name string `json:"name,omitempty" doc:"The ID of the security group. Mutually exclusive with id parameter"`
|
|
|
|
_ bool `name:"deleteSecurityGroup" description:"Deletes security group"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// Response returns the struct to unmarshal
|
|
|
|
func (DeleteSecurityGroup) Response() interface{} {
|
|
|
|
return new(BooleanResponse)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// AuthorizeSecurityGroupIngress (Async) represents the ingress rule creation
|
|
|
|
type AuthorizeSecurityGroupIngress struct {
|
2018-09-14 08:06:03 +00:00
|
|
|
CIDRList []CIDR `json:"cidrlist,omitempty" doc:"the cidr list associated"`
|
|
|
|
Description string `json:"description,omitempty" doc:"the description of the ingress/egress rule"`
|
2019-03-14 10:04:04 +00:00
|
|
|
EndPort uint16 `json:"endport,omitempty" doc:"end port for this ingress/egress rule"`
|
2018-09-14 08:06:03 +00:00
|
|
|
IcmpCode uint8 `json:"icmpcode,omitempty" doc:"error code for this icmp message"`
|
|
|
|
IcmpType uint8 `json:"icmptype,omitempty" doc:"type of the icmp message being sent"`
|
2019-03-14 10:04:04 +00:00
|
|
|
Protocol string `json:"protocol,omitempty" doc:"TCP is default. UDP, ICMP, ICMPv6, AH, ESP, GRE, IPIP are the other supported protocols"`
|
2018-09-14 08:06:03 +00:00
|
|
|
SecurityGroupID *UUID `json:"securitygroupid,omitempty" doc:"The ID of the security group. Mutually exclusive with securitygroupname parameter"`
|
|
|
|
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"The name of the security group. Mutually exclusive with securitygroupid parameter"`
|
2019-03-14 10:04:04 +00:00
|
|
|
StartPort uint16 `json:"startport,omitempty" doc:"start port for this ingress/egress rule"`
|
2018-09-14 08:06:03 +00:00
|
|
|
UserSecurityGroupList []UserSecurityGroup `json:"usersecuritygrouplist,omitempty" doc:"user to security group mapping"`
|
2019-03-14 10:04:04 +00:00
|
|
|
_ bool `name:"authorizeSecurityGroupIngress" description:"Authorize a particular ingress/egress rule for this security group"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// Response returns the struct to unmarshal
|
|
|
|
func (AuthorizeSecurityGroupIngress) Response() interface{} {
|
2018-09-14 08:06:03 +00:00
|
|
|
return new(AsyncJobResult)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// AsyncResponse returns the struct to unmarshal the async job
|
|
|
|
func (AuthorizeSecurityGroupIngress) AsyncResponse() interface{} {
|
2018-09-14 08:06:03 +00:00
|
|
|
return new(SecurityGroup)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 08:06:03 +00:00
|
|
|
func (req AuthorizeSecurityGroupIngress) onBeforeSend(params url.Values) error {
|
2018-02-12 17:10:05 +00:00
|
|
|
// ICMP code and type may be zero but can also be omitted...
|
2018-09-14 08:06:03 +00:00
|
|
|
if strings.HasPrefix(strings.ToLower(req.Protocol), "icmp") {
|
2018-02-12 17:10:05 +00:00
|
|
|
params.Set("icmpcode", strconv.FormatInt(int64(req.IcmpCode), 10))
|
|
|
|
params.Set("icmptype", strconv.FormatInt(int64(req.IcmpType), 10))
|
|
|
|
}
|
2018-09-14 08:06:03 +00:00
|
|
|
// StartPort may be zero but can also be omitted...
|
|
|
|
if req.EndPort != 0 && req.StartPort == 0 {
|
|
|
|
params.Set("startport", "0")
|
|
|
|
}
|
2018-02-12 17:10:05 +00:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
// AuthorizeSecurityGroupEgress (Async) represents the egress rule creation
|
|
|
|
type AuthorizeSecurityGroupEgress AuthorizeSecurityGroupIngress
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// Response returns the struct to unmarshal
|
|
|
|
func (AuthorizeSecurityGroupEgress) Response() interface{} {
|
2018-09-14 08:06:03 +00:00
|
|
|
return new(AsyncJobResult)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// AsyncResponse returns the struct to unmarshal the async job
|
|
|
|
func (AuthorizeSecurityGroupEgress) AsyncResponse() interface{} {
|
2018-09-14 08:06:03 +00:00
|
|
|
return new(SecurityGroup)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2018-09-14 08:06:03 +00:00
|
|
|
func (req AuthorizeSecurityGroupEgress) onBeforeSend(params url.Values) error {
|
|
|
|
return (AuthorizeSecurityGroupIngress)(req).onBeforeSend(params)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RevokeSecurityGroupIngress (Async) represents the ingress/egress rule deletion
|
|
|
|
type RevokeSecurityGroupIngress struct {
|
2018-09-14 08:06:03 +00:00
|
|
|
ID *UUID `json:"id" doc:"The ID of the ingress rule"`
|
|
|
|
_ bool `name:"revokeSecurityGroupIngress" description:"Deletes a particular ingress rule from this security group"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// Response returns the struct to unmarshal
|
|
|
|
func (RevokeSecurityGroupIngress) Response() interface{} {
|
2018-09-14 08:06:03 +00:00
|
|
|
return new(AsyncJobResult)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
2019-03-14 10:04:04 +00:00
|
|
|
|
|
|
|
// AsyncResponse returns the struct to unmarshal the async job
|
|
|
|
func (RevokeSecurityGroupIngress) AsyncResponse() interface{} {
|
|
|
|
return new(BooleanResponse)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// RevokeSecurityGroupEgress (Async) represents the ingress/egress rule deletion
|
|
|
|
type RevokeSecurityGroupEgress struct {
|
2018-09-14 08:06:03 +00:00
|
|
|
ID *UUID `json:"id" doc:"The ID of the egress rule"`
|
|
|
|
_ bool `name:"revokeSecurityGroupEgress" description:"Deletes a particular egress rule from this security group"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// Response returns the struct to unmarshal
|
|
|
|
func (RevokeSecurityGroupEgress) Response() interface{} {
|
2018-09-14 08:06:03 +00:00
|
|
|
return new(AsyncJobResult)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
// AsyncResponse returns the struct to unmarshal the async job
|
|
|
|
func (RevokeSecurityGroupEgress) AsyncResponse() interface{} {
|
|
|
|
return new(BooleanResponse)
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
2019-03-14 10:04:04 +00:00
|
|
|
//go:generate go run generate/main.go -interface=Listable ListSecurityGroups
|
|
|
|
|
2018-02-12 17:10:05 +00:00
|
|
|
// ListSecurityGroups represents a search for security groups
|
|
|
|
type ListSecurityGroups struct {
|
2019-03-14 10:04:04 +00:00
|
|
|
ID *UUID `json:"id,omitempty" doc:"list the security group by the id provided"`
|
|
|
|
Keyword string `json:"keyword,omitempty" doc:"List by keyword"`
|
|
|
|
Page int `json:"page,omitempty"`
|
|
|
|
PageSize int `json:"pagesize,omitempty"`
|
|
|
|
SecurityGroupName string `json:"securitygroupname,omitempty" doc:"lists security groups by name"`
|
|
|
|
VirtualMachineID *UUID `json:"virtualmachineid,omitempty" doc:"lists security groups by virtual machine id"`
|
|
|
|
_ bool `name:"listSecurityGroups" description:"Lists security groups"`
|
2018-02-12 17:10:05 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// ListSecurityGroupsResponse represents a list of security groups
|
|
|
|
type ListSecurityGroupsResponse struct {
|
|
|
|
Count int `json:"count"`
|
|
|
|
SecurityGroup []SecurityGroup `json:"securitygroup"`
|
|
|
|
}
|