Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 42 additions & 0 deletions openstack/dns/v2/zones/requests.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,3 +178,45 @@ func Delete(ctx context.Context, client *gophercloud.ServiceClient, zoneID strin
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// request body for sharing a zone.
type ShareOptsBuilder interface {
ToShareMap() (map[string]interface{}, error)
}

// ShareZoneOpts specifies the target project for sharing a zone.
type ShareZoneOpts struct {
// TargetProjectID is the ID of the project to share the zone with.
TargetProjectID string `json:"target_project_id" required:"true"`
}

// ToShareMap constructs a request body from a ShareZoneOpts.
func (opts ShareZoneOpts) ToShareMap() (map[string]interface{}, error) {
return map[string]interface{}{
"target_project_id": opts.TargetProjectID,
}, nil
}

// Share shares a zone with another project.
func Share(ctx context.Context, client *gophercloud.ServiceClient, zoneID string, opts ShareOptsBuilder) (r gophercloud.ErrResult) {
body, err := gophercloud.BuildRequestBody(opts, "")
if err != nil {
r.Err = err
return
}

resp, err := client.Post(ctx, zoneShareURL(client, zoneID), body, nil, &gophercloud.RequestOpts{
OkCodes: []int{201},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}

// Unshare removes a share for a zone.
func Unshare(ctx context.Context, client *gophercloud.ServiceClient, zoneID, shareID string) (r gophercloud.ErrResult) {
resp, err := client.Delete(ctx, zoneUnshareURL(client, zoneID, shareID), &gophercloud.RequestOpts{
OkCodes: []int{204},
})
_, r.Header, r.Err = gophercloud.ParseResponse(resp, err)
return
}
5 changes: 5 additions & 0 deletions openstack/dns/v2/zones/results.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,11 @@ type ZonePage struct {
pagination.LinkedPageBase
}

// ErrResult represents a generic error result.
type ErrResult struct {
gophercloud.ErrResult
}

// IsEmpty returns true if the page contains no results.
func (r ZonePage) IsEmpty() (bool, error) {
if r.StatusCode == 204 {
Expand Down
41 changes: 41 additions & 0 deletions openstack/dns/v2/zones/testing/requests_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,9 @@ package testing

import (
"context"
"encoding/json"
"io"
"net/http"
"testing"

"github.com/gophercloud/gophercloud/v2/openstack/dns/v2/zones"
Expand Down Expand Up @@ -105,3 +108,41 @@ func TestDelete(t *testing.T) {
th.AssertNoErr(t, err)
th.CheckDeepEquals(t, &DeletedZone, actual)
}

func TestShare(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

th.Mux.HandleFunc("/zones/zone-id/shares", func(w http.ResponseWriter, r *http.Request) {
th.AssertEquals(t, r.Method, "POST")

body, err := io.ReadAll(r.Body)
defer r.Body.Close()
th.AssertNoErr(t, err)

var reqBody map[string]string
err = json.Unmarshal(body, &reqBody)
th.AssertNoErr(t, err)
expectedBody := map[string]string{"target_project_id": "project-id"}
th.CheckDeepEquals(t, expectedBody, reqBody)

w.WriteHeader(http.StatusCreated)
})

opts := zones.ShareZoneOpts{TargetProjectID: "project-id"}
err := zones.Share(context.TODO(), client.ServiceClient(), "zone-id", opts).ExtractErr()
th.AssertNoErr(t, err)
}

func TestUnshare(t *testing.T) {
th.SetupHTTP()
defer th.TeardownHTTP()

th.Mux.HandleFunc("/zones/zone-id/shares/share-id", func(w http.ResponseWriter, r *http.Request) {
th.AssertEquals(t, r.Method, "DELETE")
w.WriteHeader(http.StatusNoContent)
})

err := zones.Unshare(context.TODO(), client.ServiceClient(), "zone-id", "share-id").ExtractErr()
th.AssertNoErr(t, err)
}
12 changes: 12 additions & 0 deletions openstack/dns/v2/zones/urls.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,22 @@ package zones

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

// baseURL returns the base URL for zones.
func baseURL(c *gophercloud.ServiceClient) string {
return c.ServiceURL("zones")
}

// zoneURL returns the URL for a specific zone.
func zoneURL(c *gophercloud.ServiceClient, zoneID string) string {
return c.ServiceURL("zones", zoneID)
}

// zoneShareURL returns the URL for sharing a zone.
func zoneShareURL(c *gophercloud.ServiceClient, zoneID string) string {
return c.ServiceURL("zones", zoneID, "shares")
}

// zoneUnshareURL returns the URL for unsharing a zone.
func zoneUnshareURL(c *gophercloud.ServiceClient, zoneID, shareID string) string {
return c.ServiceURL("zones", zoneID, "shares", shareID)
}
Loading