1package awsat
2
3import (
4	"testing"
5
6	"github.com/aws/aws-sdk-go/service/ec2"
7)
8
9func TestSecuritygroup(t *testing.T) {
10	t.Run("create", func(t *testing.T) {
11		Template(`create securitygroup name=my-sg-name vpc=my-vpc-id description="security group description"`).Mock(&ec2Mock{
12			CreateSecurityGroupFunc: func(input *ec2.CreateSecurityGroupInput) (*ec2.CreateSecurityGroupOutput, error) {
13				return &ec2.CreateSecurityGroupOutput{GroupId: String("new-secgroup-id")}, nil
14			}}).
15			ExpectInput("CreateSecurityGroup", &ec2.CreateSecurityGroupInput{
16				GroupName:   String("my-sg-name"),
17				VpcId:       String("my-vpc-id"),
18				Description: String("security group description"),
19			}).ExpectCommandResult("new-secgroup-id").ExpectCalls("CreateSecurityGroup").Run(t)
20	})
21
22	t.Run("update", func(t *testing.T) {
23		t.Run("inbound authorize with another secgroup", func(t *testing.T) {
24			Template("update securitygroup id=my-secgroup-id inbound=authorize protocol=tcp securitygroup=any-secgroup-id portrange=8080").Mock(&ec2Mock{
25				AuthorizeSecurityGroupIngressFunc: func(input *ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) {
26					return nil, nil
27				}}).
28				ExpectInput("AuthorizeSecurityGroupIngress", &ec2.AuthorizeSecurityGroupIngressInput{
29					GroupId: String("my-secgroup-id"),
30					IpPermissions: []*ec2.IpPermission{
31						{
32							UserIdGroupPairs: []*ec2.UserIdGroupPair{{GroupId: String("any-secgroup-id")}},
33							IpProtocol:       String("tcp"),
34							FromPort:         Int64(8080),
35							ToPort:           Int64(8080),
36						},
37					},
38				}).ExpectCalls("AuthorizeSecurityGroupIngress").Run(t)
39		})
40
41		t.Run("inbound authorize", func(t *testing.T) {
42			Template("update securitygroup id=my-secgroup-id inbound=authorize protocol=tcp cidr=10.10.10.0/24 portrange=10-22").Mock(&ec2Mock{
43				AuthorizeSecurityGroupIngressFunc: func(input *ec2.AuthorizeSecurityGroupIngressInput) (*ec2.AuthorizeSecurityGroupIngressOutput, error) {
44					return nil, nil
45				}}).
46				ExpectInput("AuthorizeSecurityGroupIngress", &ec2.AuthorizeSecurityGroupIngressInput{
47					GroupId: String("my-secgroup-id"),
48					IpPermissions: []*ec2.IpPermission{
49						{
50							IpProtocol: String("tcp"),
51							IpRanges:   []*ec2.IpRange{{CidrIp: String("10.10.10.0/24")}},
52							FromPort:   Int64(10),
53							ToPort:     Int64(22),
54						},
55					},
56				}).ExpectCalls("AuthorizeSecurityGroupIngress").Run(t)
57		})
58		t.Run("inbound revoke", func(t *testing.T) {
59			Template("update securitygroup id=my-secgroup-id inbound=revoke protocol=tcp cidr=10.10.10.0/24 portrange=10-22").Mock(&ec2Mock{
60				RevokeSecurityGroupIngressFunc: func(input *ec2.RevokeSecurityGroupIngressInput) (*ec2.RevokeSecurityGroupIngressOutput, error) {
61					return nil, nil
62				}}).
63				ExpectInput("RevokeSecurityGroupIngress", &ec2.RevokeSecurityGroupIngressInput{
64					GroupId: String("my-secgroup-id"),
65					IpPermissions: []*ec2.IpPermission{
66						{
67							IpProtocol: String("tcp"),
68							IpRanges:   []*ec2.IpRange{{CidrIp: String("10.10.10.0/24")}},
69							FromPort:   Int64(10),
70							ToPort:     Int64(22),
71						},
72					},
73				}).ExpectCalls("RevokeSecurityGroupIngress").Run(t)
74		})
75		t.Run("outbound authorize", func(t *testing.T) {
76			Template("update securitygroup id=my-secgroup-id outbound=authorize protocol=tcp cidr=10.10.10.0/24 portrange=10-22").Mock(&ec2Mock{
77				AuthorizeSecurityGroupEgressFunc: func(input *ec2.AuthorizeSecurityGroupEgressInput) (*ec2.AuthorizeSecurityGroupEgressOutput, error) {
78					return nil, nil
79				}}).
80				ExpectInput("AuthorizeSecurityGroupEgress", &ec2.AuthorizeSecurityGroupEgressInput{
81					GroupId: String("my-secgroup-id"),
82					IpPermissions: []*ec2.IpPermission{
83						{
84							IpProtocol: String("tcp"),
85							IpRanges:   []*ec2.IpRange{{CidrIp: String("10.10.10.0/24")}},
86							FromPort:   Int64(10),
87							ToPort:     Int64(22),
88						},
89					},
90				}).ExpectCalls("AuthorizeSecurityGroupEgress").Run(t)
91		})
92		t.Run("outbound revoke", func(t *testing.T) {
93			Template("update securitygroup id=my-secgroup-id outbound=revoke protocol=tcp cidr=10.10.10.0/24 portrange=10-22").Mock(&ec2Mock{
94				RevokeSecurityGroupEgressFunc: func(input *ec2.RevokeSecurityGroupEgressInput) (*ec2.RevokeSecurityGroupEgressOutput, error) {
95					return nil, nil
96				}}).
97				ExpectInput("RevokeSecurityGroupEgress", &ec2.RevokeSecurityGroupEgressInput{
98					GroupId: String("my-secgroup-id"),
99					IpPermissions: []*ec2.IpPermission{
100						{
101							IpProtocol: String("tcp"),
102							IpRanges:   []*ec2.IpRange{{CidrIp: String("10.10.10.0/24")}},
103							FromPort:   Int64(10),
104							ToPort:     Int64(22),
105						},
106					},
107				}).ExpectCalls("RevokeSecurityGroupEgress").Run(t)
108		})
109	})
110
111	t.Run("delete", func(t *testing.T) {
112		Template("delete securitygroup id=my-secgroup-id").Mock(&ec2Mock{
113			DeleteSecurityGroupFunc: func(input *ec2.DeleteSecurityGroupInput) (*ec2.DeleteSecurityGroupOutput, error) {
114				return nil, nil
115			}}).
116			ExpectInput("DeleteSecurityGroup", &ec2.DeleteSecurityGroupInput{
117				GroupId: String("my-secgroup-id"),
118			}).ExpectCalls("DeleteSecurityGroup").Run(t)
119	})
120
121	t.Run("attach", func(t *testing.T) {
122		Template("attach securitygroup id=my-secgroup-id instance=secgroup-instance-id").Mock(&ec2Mock{
123			DescribeInstanceAttributeFunc: func(input *ec2.DescribeInstanceAttributeInput) (*ec2.DescribeInstanceAttributeOutput, error) {
124				return &ec2.DescribeInstanceAttributeOutput{Groups: []*ec2.GroupIdentifier{
125					{GroupId: String("secgroup-1")}, {GroupId: String("secgroup-2")},
126				}}, nil
127			},
128			ModifyInstanceAttributeFunc: func(input *ec2.ModifyInstanceAttributeInput) (*ec2.ModifyInstanceAttributeOutput, error) {
129				return nil, nil
130			}}).
131			ExpectInput("DescribeInstanceAttribute", &ec2.DescribeInstanceAttributeInput{
132				Attribute:  String("groupSet"),
133				InstanceId: String("secgroup-instance-id"),
134			}).
135			ExpectInput("ModifyInstanceAttribute", &ec2.ModifyInstanceAttributeInput{
136				InstanceId: String("secgroup-instance-id"),
137				Groups:     []*string{String("secgroup-1"), String("secgroup-2"), String("my-secgroup-id")},
138			}).ExpectCalls("DescribeInstanceAttribute", "ModifyInstanceAttribute").Run(t)
139	})
140
141	t.Run("detach", func(t *testing.T) {
142		Template("detach securitygroup id=my-secgroup-id instance=secgroup-instance-id").Mock(&ec2Mock{
143			DescribeInstanceAttributeFunc: func(input *ec2.DescribeInstanceAttributeInput) (*ec2.DescribeInstanceAttributeOutput, error) {
144				return &ec2.DescribeInstanceAttributeOutput{Groups: []*ec2.GroupIdentifier{
145					{GroupId: String("secgroup-1")}, {GroupId: String("my-secgroup-id")},
146				}}, nil
147			},
148			ModifyInstanceAttributeFunc: func(input *ec2.ModifyInstanceAttributeInput) (*ec2.ModifyInstanceAttributeOutput, error) {
149				return nil, nil
150			}}).
151			ExpectInput("DescribeInstanceAttribute", &ec2.DescribeInstanceAttributeInput{
152				Attribute:  String("groupSet"),
153				InstanceId: String("secgroup-instance-id"),
154			}).
155			ExpectInput("ModifyInstanceAttribute", &ec2.ModifyInstanceAttributeInput{
156				InstanceId: String("secgroup-instance-id"),
157				Groups:     []*string{String("secgroup-1")},
158			}).ExpectCalls("DescribeInstanceAttribute", "ModifyInstanceAttribute").Run(t)
159	})
160
161	t.Run("check", func(t *testing.T) {
162		Template("check securitygroup id=my-secgroup-id state=unused timeout=2").Mock(&ec2Mock{
163			DescribeNetworkInterfacesFunc: func(input *ec2.DescribeNetworkInterfacesInput) (*ec2.DescribeNetworkInterfacesOutput, error) {
164				return &ec2.DescribeNetworkInterfacesOutput{
165					NetworkInterfaces: []*ec2.NetworkInterface{},
166				}, nil
167			}}).ExpectInput("DescribeNetworkInterfaces", &ec2.DescribeNetworkInterfacesInput{
168			Filters: []*ec2.Filter{{Name: String("group-id"), Values: []*string{String("my-secgroup-id")}}},
169		}).ExpectCalls("DescribeNetworkInterfaces").Run(t)
170	})
171}
172