blob: 84b2712172980921c7cb994adaae0950d405aa91 [file] [log] [blame]
Jamie Hannaford249bb622014-11-07 12:11:26 +01001package ssl
Jamie Hannaford276a0322014-11-06 14:26:12 +01002
3import (
4 "errors"
5
6 "github.com/racker/perigee"
7
8 "github.com/rackspace/gophercloud"
Jamie Hannaford249bb622014-11-07 12:11:26 +01009 "github.com/rackspace/gophercloud/pagination"
Jamie Hannaford276a0322014-11-06 14:26:12 +010010)
11
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010012var (
13 errPrivateKey = errors.New("PrivateKey is a required field")
14 errCertificate = errors.New("Certificate is a required field")
15 errIntCertificate = errors.New("IntCertificate is a required field")
16)
17
Jamie Hannaford276a0322014-11-06 14:26:12 +010018// UpdateOptsBuilder is the interface options structs have to satisfy in order
Jamie Hannafordcfe2f282014-11-07 15:11:21 +010019// to be used in the main Update operation in this package.
Jamie Hannaford276a0322014-11-06 14:26:12 +010020type UpdateOptsBuilder interface {
21 ToSSLUpdateMap() (map[string]interface{}, error)
22}
23
24// UpdateOpts is the common options struct used in this package's Update
25// operation.
26type UpdateOpts struct {
Jamie Hannaford227d9592014-11-13 10:32:07 +010027 // Required - consult the SSLTermConfig struct for more info.
Jamie Hannaford276a0322014-11-06 14:26:12 +010028 SecurePort int
29
Jamie Hannaford227d9592014-11-13 10:32:07 +010030 // Required - consult the SSLTermConfig struct for more info.
Jamie Hannaford276a0322014-11-06 14:26:12 +010031 PrivateKey string
32
Jamie Hannaford227d9592014-11-13 10:32:07 +010033 // Required - consult the SSLTermConfig struct for more info.
Jamie Hannaford276a0322014-11-06 14:26:12 +010034 Certificate string
35
Jamie Hannaford227d9592014-11-13 10:32:07 +010036 // Required - consult the SSLTermConfig struct for more info.
Jamie Hannaford276a0322014-11-06 14:26:12 +010037 IntCertificate string
38
Jamie Hannaford227d9592014-11-13 10:32:07 +010039 // Optional - consult the SSLTermConfig struct for more info.
Jamie Hannaford276a0322014-11-06 14:26:12 +010040 Enabled *bool
41
Jamie Hannaford227d9592014-11-13 10:32:07 +010042 // Optional - consult the SSLTermConfig struct for more info.
Jamie Hannaford276a0322014-11-06 14:26:12 +010043 SecureTrafficOnly *bool
44}
45
46// ToSSLUpdateMap casts a CreateOpts struct to a map.
47func (opts UpdateOpts) ToSSLUpdateMap() (map[string]interface{}, error) {
48 ssl := make(map[string]interface{})
49
50 if opts.SecurePort == 0 {
51 return ssl, errors.New("SecurePort needs to be an integer greater than 0")
52 }
53 if opts.PrivateKey == "" {
Jamie Hannaford249bb622014-11-07 12:11:26 +010054 return ssl, errPrivateKey
Jamie Hannaford276a0322014-11-06 14:26:12 +010055 }
56 if opts.Certificate == "" {
Jamie Hannaford249bb622014-11-07 12:11:26 +010057 return ssl, errCertificate
Jamie Hannaford276a0322014-11-06 14:26:12 +010058 }
59 if opts.IntCertificate == "" {
Jamie Hannaford249bb622014-11-07 12:11:26 +010060 return ssl, errIntCertificate
Jamie Hannaford276a0322014-11-06 14:26:12 +010061 }
62
63 ssl["securePort"] = opts.SecurePort
64 ssl["privateKey"] = opts.PrivateKey
65 ssl["certificate"] = opts.Certificate
Jamie Hannaford249bb622014-11-07 12:11:26 +010066 ssl["intermediateCertificate"] = opts.IntCertificate
Jamie Hannaford276a0322014-11-06 14:26:12 +010067
68 if opts.Enabled != nil {
69 ssl["enabled"] = &opts.Enabled
70 }
71
72 if opts.SecureTrafficOnly != nil {
73 ssl["secureTrafficOnly"] = &opts.SecureTrafficOnly
74 }
75
76 return map[string]interface{}{"sslTermination": ssl}, nil
77}
78
79// Update is the operation responsible for updating the SSL Termination
80// configuration for a load balancer.
81func Update(c *gophercloud.ServiceClient, lbID int, opts UpdateOptsBuilder) UpdateResult {
82 var res UpdateResult
83
84 reqBody, err := opts.ToSSLUpdateMap()
85 if err != nil {
86 res.Err = err
87 return res
88 }
89
90 _, res.Err = perigee.Request("PUT", rootURL(c, lbID), perigee.Options{
91 MoreHeaders: c.AuthenticatedHeaders(),
92 ReqBody: &reqBody,
93 Results: &res.Body,
94 OkCodes: []int{200},
95 })
96
97 return res
98}
99
100// Get is the operation responsible for showing the details of the SSL
101// Termination configuration for a load balancer.
102func Get(c *gophercloud.ServiceClient, lbID int) GetResult {
103 var res GetResult
104
105 _, res.Err = perigee.Request("GET", rootURL(c, lbID), perigee.Options{
106 MoreHeaders: c.AuthenticatedHeaders(),
107 Results: &res.Body,
108 OkCodes: []int{200},
109 })
110
111 return res
112}
113
114// Delete is the operation responsible for deleting the SSL Termination
115// configuration for a load balancer.
116func Delete(c *gophercloud.ServiceClient, lbID int) DeleteResult {
117 var res DeleteResult
118
119 _, res.Err = perigee.Request("DELETE", rootURL(c, lbID), perigee.Options{
120 MoreHeaders: c.AuthenticatedHeaders(),
121 OkCodes: []int{200},
122 })
123
124 return res
125}
Jamie Hannaford249bb622014-11-07 12:11:26 +0100126
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100127// ListCerts will list all of the certificate mappings associated with a
128// SSL-terminated HTTP load balancer.
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100129func ListCerts(c *gophercloud.ServiceClient, lbID int) pagination.Pager {
Jamie Hannaford249bb622014-11-07 12:11:26 +0100130 url := certURL(c, lbID)
131 return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page {
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100132 return CertPage{pagination.LinkedPageBase{PageResult: r}}
Jamie Hannaford249bb622014-11-07 12:11:26 +0100133 })
134}
135
Jamie Hannaford227d9592014-11-13 10:32:07 +0100136// CreateCertOptsBuilder is the interface options structs have to satisfy in
137// order to be used in the AddCert operation in this package.
138type CreateCertOptsBuilder interface {
139 ToCertCreateMap() (map[string]interface{}, error)
Jamie Hannaford249bb622014-11-07 12:11:26 +0100140}
141
Jamie Hannaford227d9592014-11-13 10:32:07 +0100142// CreateCertOpts represents the options used when adding a new certificate mapping.
143type CreateCertOpts struct {
Jamie Hannaford249bb622014-11-07 12:11:26 +0100144 HostName string
145 PrivateKey string
146 Certificate string
147 IntCertificate string
148}
149
Jamie Hannaford227d9592014-11-13 10:32:07 +0100150// ToCertCreateMap will cast an CreateCertOpts struct to a map for JSON serialization.
151func (opts CreateCertOpts) ToCertCreateMap() (map[string]interface{}, error) {
Jamie Hannaford249bb622014-11-07 12:11:26 +0100152 cm := make(map[string]interface{})
153
154 if opts.HostName == "" {
155 return cm, errors.New("HostName is a required option")
156 }
157 if opts.PrivateKey == "" {
158 return cm, errPrivateKey
159 }
160 if opts.Certificate == "" {
161 return cm, errCertificate
162 }
163
164 cm["hostName"] = opts.HostName
165 cm["privateKey"] = opts.PrivateKey
166 cm["certificate"] = opts.Certificate
167
168 if opts.IntCertificate != "" {
169 cm["intermediateCertificate"] = opts.IntCertificate
170 }
171
172 return map[string]interface{}{"certificateMapping": cm}, nil
173}
174
Jamie Hannaford227d9592014-11-13 10:32:07 +0100175// CreateCert will add a new SSL certificate and allow an SSL-terminated HTTP
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100176// load balancer to use it. This feature is useful because it allows multiple
177// certificates to be used. The maximum number of certificates that can be
178// stored per LB is 20.
Jamie Hannaford227d9592014-11-13 10:32:07 +0100179func CreateCert(c *gophercloud.ServiceClient, lbID int, opts CreateCertOptsBuilder) CreateCertResult {
180 var res CreateCertResult
Jamie Hannaford249bb622014-11-07 12:11:26 +0100181
Jamie Hannaford227d9592014-11-13 10:32:07 +0100182 reqBody, err := opts.ToCertCreateMap()
Jamie Hannaford249bb622014-11-07 12:11:26 +0100183 if err != nil {
184 res.Err = err
185 return res
186 }
187
188 _, res.Err = perigee.Request("POST", certURL(c, lbID), perigee.Options{
189 MoreHeaders: c.AuthenticatedHeaders(),
190 ReqBody: &reqBody,
191 Results: &res.Body,
192 OkCodes: []int{200},
193 })
194
195 return res
196}
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100197
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100198// GetCert will show the details of an existing SSL certificate.
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100199func GetCert(c *gophercloud.ServiceClient, lbID, certID int) GetCertResult {
200 var res GetCertResult
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100201
202 _, res.Err = perigee.Request("GET", certResourceURL(c, lbID, certID), perigee.Options{
203 MoreHeaders: c.AuthenticatedHeaders(),
204 Results: &res.Body,
205 OkCodes: []int{200},
206 })
207
208 return res
209}
210
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100211// UpdateCertOptsBuilder is the interface options structs have to satisfy in
212// order to be used in the UpdateCert operation in this package.
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100213type UpdateCertOptsBuilder interface {
214 ToCertUpdateMap() (map[string]interface{}, error)
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100215}
216
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100217// UpdateCertOpts represents the options needed to update a SSL certificate.
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100218type UpdateCertOpts struct {
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100219 HostName string
220 PrivateKey string
221 Certificate string
222 IntCertificate string
223}
224
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100225// ToCertUpdateMap will cast an UpdateCertOpts struct into a map for JSON
226// seralization.
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100227func (opts UpdateCertOpts) ToCertUpdateMap() (map[string]interface{}, error) {
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100228 cm := make(map[string]interface{})
229
230 if opts.HostName != "" {
231 cm["hostName"] = opts.HostName
232 }
233 if opts.PrivateKey != "" {
234 cm["privateKey"] = opts.PrivateKey
235 }
236 if opts.Certificate != "" {
237 cm["certificate"] = opts.Certificate
238 }
239 if opts.IntCertificate != "" {
240 cm["intermediateCertificate"] = opts.IntCertificate
241 }
242
243 return map[string]interface{}{"certificateMapping": cm}, nil
244}
245
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100246// UpdateCert is the operation responsible for updating the details of an
247// existing SSL certificate.
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100248func UpdateCert(c *gophercloud.ServiceClient, lbID, certID int, opts UpdateCertOptsBuilder) UpdateCertResult {
249 var res UpdateCertResult
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100250
Jamie Hannafordb65793f2014-11-07 13:45:06 +0100251 reqBody, err := opts.ToCertUpdateMap()
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100252 if err != nil {
253 res.Err = err
254 return res
255 }
256
257 _, res.Err = perigee.Request("PUT", certResourceURL(c, lbID, certID), perigee.Options{
258 MoreHeaders: c.AuthenticatedHeaders(),
259 ReqBody: &reqBody,
260 Results: &res.Body,
261 OkCodes: []int{202},
262 })
263
264 return res
265}
266
Jamie Hannafordcfe2f282014-11-07 15:11:21 +0100267// DeleteCert is the operation responsible for permanently removing a SSL
268// certificate.
Jamie Hannafordcba541e2014-11-07 13:36:54 +0100269func DeleteCert(c *gophercloud.ServiceClient, lbID, certID int) DeleteResult {
270 var res DeleteResult
271
272 _, res.Err = perigee.Request("DELETE", certResourceURL(c, lbID, certID), perigee.Options{
273 MoreHeaders: c.AuthenticatedHeaders(),
274 OkCodes: []int{200},
275 })
276
277 return res
278}