blob: 00b25205f154b1da1e193a6a73f53f4ea9b28d63 [file] [log] [blame]
Jon Perritt12395212016-02-24 10:41:17 -06001package floatingips
Joe Topjiandee32222015-02-09 23:56:26 +00002
3import (
Jon Perritt27249f42016-02-18 10:35:59 -06004 "github.com/gophercloud/gophercloud"
5 "github.com/gophercloud/gophercloud/pagination"
Joe Topjiandee32222015-02-09 23:56:26 +00006)
7
8// List returns a Pager that allows you to iterate over a collection of FloatingIPs.
9func List(client *gophercloud.ServiceClient) pagination.Pager {
10 return pagination.NewPager(client, listURL(client), func(r pagination.PageResult) pagination.Page {
Jon Perritt12395212016-02-24 10:41:17 -060011 return FloatingIPPage{pagination.SinglePageBase(r)}
Joe Topjiandee32222015-02-09 23:56:26 +000012 })
13}
14
15// CreateOptsBuilder describes struct types that can be accepted by the Create call. Notable, the
16// CreateOpts struct in this package does.
17type CreateOptsBuilder interface {
18 ToFloatingIPCreateMap() (map[string]interface{}, error)
19}
20
21// CreateOpts specifies a Floating IP allocation request
22type CreateOpts struct {
23 // Pool is the pool of floating IPs to allocate one from
24 Pool string
25}
26
Joe Topjiand97fe9b2015-09-17 02:08:38 +000027// AssociateOpts specifies the required information to associate or disassociate a floating IP to an instance
28type AssociateOpts struct {
29 // ServerID is the UUID of the server
30 ServerID string
31
32 // FixedIP is an optional fixed IP address of the server
33 FixedIP string
34
35 // FloatingIP is the floating IP to associate with an instance
36 FloatingIP string
37}
38
Joe Topjiandee32222015-02-09 23:56:26 +000039// ToFloatingIPCreateMap constructs a request body from CreateOpts.
40func (opts CreateOpts) ToFloatingIPCreateMap() (map[string]interface{}, error) {
41 if opts.Pool == "" {
Jon Perrittf094fef2016-03-07 01:41:59 -060042 err := gophercloud.ErrMissingInput{}
43 err.Function = "floatingips.ToFloatingIPCreateMap"
44 err.Argument = "floatingips.CreateOpts.Pool"
45 return nil, err
Joe Topjiandee32222015-02-09 23:56:26 +000046 }
47
48 return map[string]interface{}{"pool": opts.Pool}, nil
49}
50
Joe Topjiand97fe9b2015-09-17 02:08:38 +000051// ToAssociateMap constructs a request body from AssociateOpts.
52func (opts AssociateOpts) ToAssociateMap() (map[string]interface{}, error) {
53 if opts.ServerID == "" {
Jon Perrittf094fef2016-03-07 01:41:59 -060054 err := gophercloud.ErrMissingInput{}
55 err.Function = "floatingips.ToAssociateMap"
56 err.Argument = "floatingips.AssociateOpts.ServerID"
57 return nil, err
Joe Topjiand97fe9b2015-09-17 02:08:38 +000058 }
59
60 if opts.FloatingIP == "" {
Jon Perrittf094fef2016-03-07 01:41:59 -060061 err := gophercloud.ErrMissingInput{}
62 err.Function = "floatingips.ToAssociateMap"
63 err.Argument = "floatingips.AssociateOpts.FloatingIP"
64 return nil, err
Joe Topjiand97fe9b2015-09-17 02:08:38 +000065 }
66
67 associateInfo := map[string]interface{}{
68 "serverId": opts.ServerID,
69 "floatingIp": opts.FloatingIP,
70 "fixedIp": opts.FixedIP,
71 }
72
73 return associateInfo, nil
74
75}
76
Joe Topjiandee32222015-02-09 23:56:26 +000077// Create requests the creation of a new floating IP
78func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) CreateResult {
79 var res CreateResult
80
81 reqBody, err := opts.ToFloatingIPCreateMap()
82 if err != nil {
83 res.Err = err
84 return res
85 }
86
Jamie Hannaford6a3a78f2015-03-24 14:56:12 +010087 _, res.Err = client.Post(createURL(client), reqBody, &res.Body, &gophercloud.RequestOpts{
88 OkCodes: []int{200},
Joe Topjiandee32222015-02-09 23:56:26 +000089 })
90 return res
91}
92
93// Get returns data about a previously created FloatingIP.
94func Get(client *gophercloud.ServiceClient, id string) GetResult {
95 var res GetResult
Jamie Hannaford6a3a78f2015-03-24 14:56:12 +010096 _, res.Err = client.Get(getURL(client, id), &res.Body, nil)
Joe Topjiandee32222015-02-09 23:56:26 +000097 return res
98}
99
100// Delete requests the deletion of a previous allocated FloatingIP.
101func Delete(client *gophercloud.ServiceClient, id string) DeleteResult {
102 var res DeleteResult
Jamie Hannaford6a3a78f2015-03-24 14:56:12 +0100103 _, res.Err = client.Delete(deleteURL(client, id), nil)
Joe Topjiandee32222015-02-09 23:56:26 +0000104 return res
105}
106
107// association / disassociation
108
109// Associate pairs an allocated floating IP with an instance
Joe Topjian94e4cc52016-01-05 17:01:18 +0000110// Deprecated. Use AssociateInstance.
Joe Topjiandee32222015-02-09 23:56:26 +0000111func Associate(client *gophercloud.ServiceClient, serverId, fip string) AssociateResult {
112 var res AssociateResult
113
114 addFloatingIp := make(map[string]interface{})
115 addFloatingIp["address"] = fip
116 reqBody := map[string]interface{}{"addFloatingIp": addFloatingIp}
117
Jamie Hannaford6a3a78f2015-03-24 14:56:12 +0100118 _, res.Err = client.Post(associateURL(client, serverId), reqBody, nil, nil)
Joe Topjiandee32222015-02-09 23:56:26 +0000119 return res
120}
121
Joe Topjian94e4cc52016-01-05 17:01:18 +0000122// AssociateInstance pairs an allocated floating IP with an instance.
123func AssociateInstance(client *gophercloud.ServiceClient, opts AssociateOpts) AssociateResult {
Joe Topjiand97fe9b2015-09-17 02:08:38 +0000124 var res AssociateResult
125
126 associateInfo, err := opts.ToAssociateMap()
127 if err != nil {
128 res.Err = err
129 return res
130 }
131
132 addFloatingIp := make(map[string]interface{})
133 addFloatingIp["address"] = associateInfo["floatingIp"].(string)
134
135 // fixedIp is not required
136 if associateInfo["fixedIp"] != "" {
137 addFloatingIp["fixed_address"] = associateInfo["fixedIp"].(string)
138 }
139
140 serverId := associateInfo["serverId"].(string)
141
142 reqBody := map[string]interface{}{"addFloatingIp": addFloatingIp}
143 _, res.Err = client.Post(associateURL(client, serverId), reqBody, nil, nil)
144 return res
145}
146
Joe Topjiandee32222015-02-09 23:56:26 +0000147// Disassociate decouples an allocated floating IP from an instance
Joe Topjian94e4cc52016-01-05 17:01:18 +0000148// Deprecated. Use DisassociateInstance.
Joe Topjiandee32222015-02-09 23:56:26 +0000149func Disassociate(client *gophercloud.ServiceClient, serverId, fip string) DisassociateResult {
150 var res DisassociateResult
151
152 removeFloatingIp := make(map[string]interface{})
153 removeFloatingIp["address"] = fip
154 reqBody := map[string]interface{}{"removeFloatingIp": removeFloatingIp}
155
Jamie Hannaford6a3a78f2015-03-24 14:56:12 +0100156 _, res.Err = client.Post(disassociateURL(client, serverId), reqBody, nil, nil)
Joe Topjiandee32222015-02-09 23:56:26 +0000157 return res
158}
Joe Topjiand97fe9b2015-09-17 02:08:38 +0000159
Joe Topjian94e4cc52016-01-05 17:01:18 +0000160// DisassociateInstance decouples an allocated floating IP from an instance
161func DisassociateInstance(client *gophercloud.ServiceClient, opts AssociateOpts) DisassociateResult {
Joe Topjiand97fe9b2015-09-17 02:08:38 +0000162 var res DisassociateResult
163
164 associateInfo, err := opts.ToAssociateMap()
165 if err != nil {
166 res.Err = err
167 return res
168 }
169
170 removeFloatingIp := make(map[string]interface{})
171 removeFloatingIp["address"] = associateInfo["floatingIp"].(string)
172 reqBody := map[string]interface{}{"removeFloatingIp": removeFloatingIp}
173
174 serverId := associateInfo["serverId"].(string)
175
176 _, res.Err = client.Post(disassociateURL(client, serverId), reqBody, nil, nil)
177 return res
178}