Skip to content

Commit ec83492

Browse files
authored
Merge pull request #3294 from gophercloud/bp-v2-a0214a5-05687fb
[v2] Add support for zone sharing in DNS v2
2 parents 297e9ec + 979e4c8 commit ec83492

File tree

4 files changed

+100
-0
lines changed

4 files changed

+100
-0
lines changed

openstack/dns/v2/zones/requests.go

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,3 +178,45 @@ func Delete(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin
178178
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
179179
return
180180
}
181+
182+
// request body for sharing a zone.
183+
type ShareOptsBuilder interface {
184+
ToShareMap() (map[string]interface{}, error)
185+
}
186+
187+
// ShareZoneOpts specifies the target project for sharing a zone.
188+
type ShareZoneOpts struct {
189+
// TargetProjectID is the ID of the project to share the zone with.
190+
TargetProjectID string `json:"target_project_id" required:"true"`
191+
}
192+
193+
// ToShareMap constructs a request body from a ShareZoneOpts.
194+
func (opts ShareZoneOpts) ToShareMap() (map[string]interface{}, error) {
195+
return map[string]interface{}{
196+
"target_project_id": opts.TargetProjectID,
197+
}, nil
198+
}
199+
200+
// Share shares a zone with another project.
201+
func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts ShareOptsBuilder) (r gophercloud.ErrResult) {
202+
body, err := gophercloud.BuildRequestBody(opts, "")
203+
if err != nil {
204+
r.Err = err
205+
return
206+
}
207+
208+
resp, err := client.Post(ctx, zoneShareURL(client, zoneID), body, nil, &gophercloud.RequestOpts{
209+
OkCodes: []int{201},
210+
})
211+
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
212+
return
213+
}
214+
215+
// Unshare removes a share for a zone.
216+
func Unshare(ctx context.Context, client *gophercloud.ServiceClient, zoneID, shareID string) (r gophercloud.ErrResult) {
217+
resp, err := client.Delete(ctx, zoneUnshareURL(client, zoneID, shareID), &gophercloud.RequestOpts{
218+
OkCodes: []int{204},
219+
})
220+
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
221+
return
222+
}

openstack/dns/v2/zones/results.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,11 @@ type ZonePage struct {
5050
pagination.LinkedPageBase
5151
}
5252

53+
// ErrResult represents a generic error result.
54+
type ErrResult struct {
55+
gophercloud.ErrResult
56+
}
57+
5358
// IsEmpty returns true if the page contains no results.
5459
func (r ZonePage) IsEmpty() (bool, error) {
5560
if r.StatusCode == 204 {

openstack/dns/v2/zones/testing/requests_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package testing
22

33
import (
44
"context"
5+
"encoding/json"
6+
"io"
7+
"net/http"
58
"testing"
69

710
"github.com/gophercloud/gophercloud/v2/openstack/dns/v2/zones"
@@ -105,3 +108,41 @@ func TestDelete(t *testing.T) {
105108
th.AssertNoErr(t, err)
106109
th.CheckDeepEquals(t, &DeletedZone, actual)
107110
}
111+
112+
func TestShare(t *testing.T) {
113+
th.SetupHTTP()
114+
defer th.TeardownHTTP()
115+
116+
th.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) {
117+
th.AssertEquals(t, r.Method, "POST")
118+
119+
body, err := io.ReadAll(r.Body)
120+
defer r.Body.Close()
121+
th.AssertNoErr(t, err)
122+
123+
var reqBody map[string]string
124+
err = json.Unmarshal(body, &reqBody)
125+
th.AssertNoErr(t, err)
126+
expectedBody := map[string]string{"target_project_id": "project-id"}
127+
th.CheckDeepEquals(t, expectedBody, reqBody)
128+
129+
w.WriteHeader(http.StatusCreated)
130+
})
131+
132+
opts := zones.ShareZoneOpts{TargetProjectID: "project-id"}
133+
err := zones.Share(context.TODO(), client.ServiceClient(), "zone-id", opts).ExtractErr()
134+
th.AssertNoErr(t, err)
135+
}
136+
137+
func TestUnshare(t *testing.T) {
138+
th.SetupHTTP()
139+
defer th.TeardownHTTP()
140+
141+
th.Mux.HandleFunc("/zones/zone-id/shares/share-id", func(w http.ResponseWriter, r *http.Request) {
142+
th.AssertEquals(t, r.Method, "DELETE")
143+
w.WriteHeader(http.StatusNoContent)
144+
})
145+
146+
err := zones.Unshare(context.TODO(), client.ServiceClient(), "zone-id", "share-id").ExtractErr()
147+
th.AssertNoErr(t, err)
148+
}

openstack/dns/v2/zones/urls.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,22 @@ package zones
22

33
import "github.com/gophercloud/gophercloud/v2"
44

5+
// baseURL returns the base URL for zones.
56
func baseURL(c *gophercloud.ServiceClient) string {
67
return c.ServiceURL("zones")
78
}
89

10+
// zoneURL returns the URL for a specific zone.
911
func zoneURL(c *gophercloud.ServiceClient, zoneID string) string {
1012
return c.ServiceURL("zones", zoneID)
1113
}
14+
15+
// zoneShareURL returns the URL for sharing a zone.
16+
func zoneShareURL(c *gophercloud.ServiceClient, zoneID string) string {
17+
return c.ServiceURL("zones", zoneID, "shares")
18+
}
19+
20+
// zoneUnshareURL returns the URL for unsharing a zone.
21+
func zoneUnshareURL(c *gophercloud.ServiceClient, zoneID, shareID string) string {
22+
return c.ServiceURL("zones", zoneID, "shares", shareID)
23+
}

0 commit comments

Comments
 (0)