blob: a91922dc3eb633ffb25e225e11ff7a3512379d01 [file] [log] [blame]
Jamie Hannaford924c09d2014-11-19 12:05:38 +01001package secgroups
2
3import (
Jamie Hannaford8badf1e2014-11-19 14:39:26 +01004 "errors"
5
Jamie Hannaforda493e642014-11-19 12:40:30 +01006 "github.com/racker/perigee"
7
Jamie Hannaford924c09d2014-11-19 12:05:38 +01008 "github.com/rackspace/gophercloud"
9 "github.com/rackspace/gophercloud/pagination"
10)
11
Jamie Hannaford19151792014-11-19 12:46:47 +010012func commonList(client *gophercloud.ServiceClient, url string) pagination.Pager {
Jamie Hannaford924c09d2014-11-19 12:05:38 +010013 createPage := func(r pagination.PageResult) pagination.Page {
14 return SecurityGroupPage{pagination.SinglePageBase(r)}
15 }
16
Jamie Hannaford19151792014-11-19 12:46:47 +010017 return pagination.NewPager(client, url, createPage)
18}
19
20func List(client *gophercloud.ServiceClient) pagination.Pager {
21 return commonList(client, rootURL(client))
22}
23
24func ListByServer(client *gophercloud.ServiceClient, serverID string) pagination.Pager {
25 return commonList(client, listByServerURL(client, serverID))
Jamie Hannaford924c09d2014-11-19 12:05:38 +010026}
Jamie Hannaforda493e642014-11-19 12:40:30 +010027
Jamie Hannaford30c74662014-11-19 15:37:34 +010028type GroupOpts struct {
Jamie Hannaforda493e642014-11-19 12:40:30 +010029 // Optional - the name of your security group. If no value provided, null
30 // will be set.
31 Name string `json:"name,omitempty"`
32
33 // Optional - the description of your security group. If no value provided,
34 // null will be set.
35 Description string `json:"description,omitempty"`
36}
37
Jamie Hannaford30c74662014-11-19 15:37:34 +010038type CreateOpts GroupOpts
39
Jamie Hannaforda493e642014-11-19 12:40:30 +010040func Create(client *gophercloud.ServiceClient, opts CreateOpts) CreateResult {
41 var result CreateResult
42
43 reqBody := struct {
44 CreateOpts `json:"security_group"`
45 }{opts}
46
47 _, result.Err = perigee.Request("POST", rootURL(client), perigee.Options{
48 Results: &result.Body,
49 ReqBody: &reqBody,
50 MoreHeaders: client.AuthenticatedHeaders(),
51 OkCodes: []int{200},
52 })
53
54 return result
55}
Jamie Hannafordb38dd312014-11-19 13:02:11 +010056
Jamie Hannaford30c74662014-11-19 15:37:34 +010057type UpdateOpts GroupOpts
58
59func Update(client *gophercloud.ServiceClient, id string, opts UpdateOpts) UpdateResult {
60 var result UpdateResult
61
62 reqBody := struct {
63 UpdateOpts `json:"security_group"`
64 }{opts}
65
Jamie Hannaford740e4a32014-11-19 16:13:30 +010066 _, result.Err = perigee.Request("PUT", resourceURL(client, id), perigee.Options{
Jamie Hannaford30c74662014-11-19 15:37:34 +010067 Results: &result.Body,
68 ReqBody: &reqBody,
69 MoreHeaders: client.AuthenticatedHeaders(),
70 OkCodes: []int{200},
71 })
72
73 return result
74}
75
Jamie Hannafordb38dd312014-11-19 13:02:11 +010076func Get(client *gophercloud.ServiceClient, id string) GetResult {
77 var result GetResult
78
79 _, result.Err = perigee.Request("GET", resourceURL(client, id), perigee.Options{
80 Results: &result.Body,
81 MoreHeaders: client.AuthenticatedHeaders(),
82 OkCodes: []int{200},
83 })
84
85 return result
86}
Jamie Hannafordd276e612014-11-19 13:56:28 +010087
88func Delete(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult {
89 var result gophercloud.ErrResult
90
91 _, result.Err = perigee.Request("DELETE", resourceURL(client, id), perigee.Options{
92 MoreHeaders: client.AuthenticatedHeaders(),
93 OkCodes: []int{202},
94 })
95
96 return result
97}
Jamie Hannaford8badf1e2014-11-19 14:39:26 +010098
99type AddRuleOpts struct {
100 // Required - the ID of the group that this rule will be added to.
101 ParentGroupID string `json:"parent_group_id"`
102
103 // Required - the lower bound of the port range that will be opened.
104 FromPort int `json:"from_port"`
105
106 // Required - the upper bound of the port range that will be opened.
107 ToPort int `json:"to_port"`
108
109 // Required - the protocol type that will be allowed, e.g. TCP.
110 IPProtocol string `json:"ip_protocol"`
111
112 // ONLY required if FromGroupID is blank. This represents the IP range that
113 // will be the source of network traffic to your security group. Use
114 // 0.0.0.0/0 to allow all IP addresses.
115 CIDR string `json:"cidr,omitempty"`
116
117 // ONLY required if CIDR is blank. This value represents the ID of a group
118 // that forwards traffic to the parent group. So, instead of accepting
119 // network traffic from an entire IP range, you can instead refine the
120 // inbound source by an existing security group.
121 FromGroupID string `json:"group_id,omitempty"`
122}
123
124func AddRule(client *gophercloud.ServiceClient, opts AddRuleOpts) AddRuleResult {
125 var result AddRuleResult
126
127 if opts.ParentGroupID == "" {
128 result.Err = errors.New("A ParentGroupID must be set")
129 return result
130 }
131 if opts.FromPort == 0 {
132 result.Err = errors.New("A FromPort must be set")
133 return result
134 }
135 if opts.ToPort == 0 {
136 result.Err = errors.New("A ToPort must be set")
137 return result
138 }
139 if opts.IPProtocol == "" {
140 result.Err = errors.New("A IPProtocol must be set")
141 return result
142 }
143 if opts.CIDR == "" && opts.FromGroupID == "" {
144 result.Err = errors.New("A CIDR or FromGroupID must be set")
145 return result
146 }
147
148 reqBody := struct {
149 AddRuleOpts `json:"security_group_rule"`
150 }{opts}
151
152 _, result.Err = perigee.Request("POST", rootRuleURL(client), perigee.Options{
153 Results: &result.Body,
154 ReqBody: &reqBody,
155 MoreHeaders: client.AuthenticatedHeaders(),
156 OkCodes: []int{200},
157 })
158
159 return result
160}
Jamie Hannaford61f81ca2014-11-19 14:44:33 +0100161
162func DeleteRule(client *gophercloud.ServiceClient, id string) gophercloud.ErrResult {
163 var result gophercloud.ErrResult
164
165 _, result.Err = perigee.Request("DELETE", resourceRuleURL(client, id), perigee.Options{
166 MoreHeaders: client.AuthenticatedHeaders(),
167 OkCodes: []int{202},
168 })
169
170 return result
171}
Jamie Hannaford740e4a32014-11-19 16:13:30 +0100172
173func actionMap(prefix, groupName string) map[string]map[string]string {
174 return map[string]map[string]string{
175 prefix + "SecurityGroup": map[string]string{"name": groupName},
176 }
177}
178
179func AddServerToGroup(client *gophercloud.ServiceClient, serverID, groupName string) gophercloud.ErrResult {
180 var result gophercloud.ErrResult
181
182 _, result.Err = perigee.Request("POST", serverActionURL(client, serverID), perigee.Options{
183 Results: &result.Body,
184 ReqBody: actionMap("add", groupName),
185 MoreHeaders: client.AuthenticatedHeaders(),
Jamie Hannafordd8ac5bb2014-11-20 12:01:37 +0100186 OkCodes: []int{202},
Jamie Hannaford740e4a32014-11-19 16:13:30 +0100187 })
188
189 return result
190}
191
192func RemoveServerFromGroup(client *gophercloud.ServiceClient, serverID, groupName string) gophercloud.ErrResult {
193 var result gophercloud.ErrResult
194
195 _, result.Err = perigee.Request("POST", serverActionURL(client, serverID), perigee.Options{
196 Results: &result.Body,
197 ReqBody: actionMap("remove", groupName),
198 MoreHeaders: client.AuthenticatedHeaders(),
Jamie Hannafordd8ac5bb2014-11-20 12:01:37 +0100199 OkCodes: []int{202},
Jamie Hannaford740e4a32014-11-19 16:13:30 +0100200 })
201
202 return result
203}