Skip to content
2 changes: 2 additions & 0 deletions client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ type Client struct {
Roles *RoleClient
Root *RootClient
Routes *RouteClient
RoutePolicies *RoutePolicyClient
SecurityGroups *SecurityGroupClient
ServiceBrokers *ServiceBrokerClient
ServiceCredentialBindings *ServiceCredentialBindingClient
Expand Down Expand Up @@ -110,6 +111,7 @@ func New(config *config.Config) (*Client, error) {
client.Roles = (*RoleClient)(&client.common)
client.Root = (*RootClient)(&client.common)
client.Routes = (*RouteClient)(&client.common)
client.RoutePolicies = (*RoutePolicyClient)(&client.common)
client.SecurityGroups = (*SecurityGroupClient)(&client.common)
client.ServiceBrokers = (*ServiceBrokerClient)(&client.common)
client.ServiceCredentialBindings = (*ServiceCredentialBindingClient)(&client.common)
Expand Down
97 changes: 97 additions & 0 deletions client/route_policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
package client
Comment thread
metskem marked this conversation as resolved.

import (
"context"
"net/url"

"github.com/cloudfoundry/go-cfclient/v3/internal/path"
"github.com/cloudfoundry/go-cfclient/v3/resource"
)

type RoutePolicyClient commonClient

// RoutePolicyListOptions list filters
type RoutePolicyListOptions struct {
*ListOptions

RouteGUIDs Filter `qs:"route_guids"`
Comment thread
metskem marked this conversation as resolved.
Outdated
SpaceGUIDs Filter `qs:"space_guids"`
SourceGUIDs Filter `qs:"source_guids"`
Sources Filter `qs:"sources"`
OrganizationGUIDs Filter `qs:"organization_guids"`
}

// NewRoutePolicyListOptions creates new options to pass to list
func NewRoutePolicyListOptions() *RoutePolicyListOptions {
return &RoutePolicyListOptions{
ListOptions: NewListOptions(),
}
}

func (o RoutePolicyListOptions) ToQueryString() (url.Values, error) {
return o.ListOptions.ToQueryString(o)
}

// Create a new route policy
func (c *RoutePolicyClient) Create(ctx context.Context, r *resource.RoutePolicyCreate) (*resource.RoutePolicy, error) {
var routePolicy resource.RoutePolicy
_, err := c.client.post(ctx, "/v3/route_policies", r, &routePolicy)
if err != nil {
return nil, err
}
return &routePolicy, nil
}

Comment thread
metskem marked this conversation as resolved.
// Delete the specified route policy asynchronously and return a jobGUID.
func (c *RoutePolicyClient) Delete(ctx context.Context, guid string) (string, error) {
return c.client.delete(ctx, path.Format("/v3/route_policies/%s", guid))
}

// First returns the first route policy matching the options or an error when less than 1 match
func (c *RoutePolicyClient) First(ctx context.Context, opts *RoutePolicyListOptions) (*resource.RoutePolicy, error) {
return First[*RoutePolicyListOptions, *resource.RoutePolicy](opts, func(opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, *Pager, error) {
return c.List(ctx, opts)
})
}

// Get the specified route policy
func (c *RoutePolicyClient) Get(ctx context.Context, guid string) (*resource.RoutePolicy, error) {
var routePolicy resource.RoutePolicy
err := c.client.get(ctx, path.Format("/v3/route_policies/%s", guid), &routePolicy)
if err != nil {
return nil, err
}
return &routePolicy, nil
}

// List pages all the route policies the user has access to
func (c *RoutePolicyClient) List(ctx context.Context, opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, *Pager, error) {
if opts == nil {
opts = NewRoutePolicyListOptions()
}

var res resource.RoutePolicyList
err := c.client.list(ctx, "/v3/route_policies", opts.ToQueryString, &res)
if err != nil {
return nil, nil, err
}
pager := NewPager(res.Pagination)
return res.Resources, pager, nil
}

// ListAll retrieves all route policies the user has access to
func (c *RoutePolicyClient) ListAll(ctx context.Context, opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, error) {
if opts == nil {
opts = NewRoutePolicyListOptions()
}
return AutoPage[*RoutePolicyListOptions, *resource.RoutePolicy](opts, func(opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, *Pager, error) {
return c.List(ctx, opts)
})
}

// Single returns a single route policy matching the options or an error if not exactly 1 match
func (c *RoutePolicyClient) Single(ctx context.Context, opts *RoutePolicyListOptions) (*resource.RoutePolicy, error) {
return Single[*RoutePolicyListOptions, *resource.RoutePolicy](opts, func(opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, *Pager, error) {
return c.List(ctx, opts)
})
}
267 changes: 267 additions & 0 deletions client/route_policy_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
package client
Comment thread
metskem marked this conversation as resolved.

import (
"context"
"net/http"
"testing"

"github.com/cloudfoundry/go-cfclient/v3/resource"
"github.com/cloudfoundry/go-cfclient/v3/testutil"
)

func TestRoutePolicies(t *testing.T) {
g := testutil.NewObjectJSONGenerator()
routePolicy := g.RoutePolicy().JSON
routePolicy2 := g.RoutePolicy().JSON

tests := []RouteTest{
{
Description: "Create route policy",
Route: testutil.MockRoute{
Method: "POST",
Endpoint: "/v3/route_policies",
Output: g.Single(routePolicy),
Status: http.StatusCreated,
PostForm: `{
"source": "1cb006ee-fb05-47e1-b541-c34179ddc446",
"relationships": {
"route": {
"data": { "guid": "5a85c020-3e3d-42a5-a475-5084c5357e82" }
},
"app": {
"data": { "guid": "1cb006ee-fb05-47e1-b541-c34179ddc446" }
}
}
}`,
},
Expected: routePolicy,
Action: func(c *Client, t *testing.T) (any, error) {
r := &resource.RoutePolicyCreate{
Source: "1cb006ee-fb05-47e1-b541-c34179ddc446",
Relationships: resource.RoutePolicyRelationships{
Route: &resource.ToOneRelationship{
Data: &resource.Relationship{
GUID: "5a85c020-3e3d-42a5-a475-5084c5357e82",
},
},
App: &resource.ToOneRelationship{
Data: &resource.Relationship{
GUID: "1cb006ee-fb05-47e1-b541-c34179ddc446",
},
},
},
}
return c.RoutePolicies.Create(context.Background(), r)
},
},
{
Description: "Delete route policy",
Route: testutil.MockRoute{
Method: "DELETE",
Endpoint: "/v3/route_policies/c8dcf27f-39a3-466a-9cbf-1d3c31a43b93",
Status: http.StatusAccepted,
RedirectLocation: "https://api.example.org/api/v3/jobs/c33a5caf-77e0-4d6e-b587-5555d339bc9a",
},
Expected: "c33a5caf-77e0-4d6e-b587-5555d339bc9a",
Action: func(c *Client, t *testing.T) (any, error) {
return c.RoutePolicies.Delete(context.Background(), "c8dcf27f-39a3-466a-9cbf-1d3c31a43b93")
},
},
{
Description: "Get route policy",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies/c8dcf27f-39a3-466a-9cbf-1d3c31a43b93",
Output: g.Single(routePolicy),
Status: http.StatusOK,
},
Expected: routePolicy,
Action: func(c *Client, t *testing.T) (any, error) {
return c.RoutePolicies.Get(context.Background(), "c8dcf27f-39a3-466a-9cbf-1d3c31a43b93")
},
},
{
Description: "List first page of route policies",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: g.Array(routePolicy),
Action: func(c *Client, t *testing.T) (any, error) {
policies, _, err := c.RoutePolicies.List(context.Background(), NewRoutePolicyListOptions())
return policies, err
},
},
{
Description: "List all route policies",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
Output: g.Paged([]string{routePolicy}, []string{routePolicy2}),
Status: http.StatusOK,
},
Expected: g.Array(routePolicy, routePolicy2),
Action: func(c *Client, t *testing.T) (any, error) {
return c.RoutePolicies.ListAll(context.Background(), nil)
},
},
{
Description: "First route policy with no matches",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
Output: g.Paged([]string{}),
Status: http.StatusOK,
},
Expected: "error",
Action: func(c *Client, t *testing.T) (any, error) {
_, err := c.RoutePolicies.First(context.Background(), NewRoutePolicyListOptions())
if err != nil {
return "error", nil
}
return "no error", nil
},
},
{
Description: "First route policy",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: routePolicy,
Action: func(c *Client, t *testing.T) (any, error) {
return c.RoutePolicies.First(context.Background(), NewRoutePolicyListOptions())
},
},
{
Description: "Single route policy with no matches",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
Output: g.Paged([]string{}),
Status: http.StatusOK,
},
Expected: "error",
Action: func(c *Client, t *testing.T) (any, error) {
_, err := c.RoutePolicies.Single(context.Background(), NewRoutePolicyListOptions())
if err != nil {
return "error", nil
}
return "no error", nil
},
},
{
Description: "Single route policy",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: routePolicy,
Action: func(c *Client, t *testing.T) (any, error) {
return c.RoutePolicies.Single(context.Background(), NewRoutePolicyListOptions())
},
},
{
Description: "List route policies with filter by route GUID",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
QueryString: "page=1&per_page=50&route_guids=5a85c020-3e3d-42a5-a475-5084c5357e82",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: g.Array(routePolicy),
Action: func(c *Client, t *testing.T) (any, error) {
opts := NewRoutePolicyListOptions()
opts.RouteGUIDs = Filter{
Values: []string{"5a85c020-3e3d-42a5-a475-5084c5357e82"},
}
policies, _, err := c.RoutePolicies.List(context.Background(), opts)
return policies, err
},
},
{
Description: "List route policies with filter by space GUID",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
QueryString: "page=1&per_page=50&space_guids=33d27af8-788d-4de5-8f37-fb80d517f2ed",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: g.Array(routePolicy),
Action: func(c *Client, t *testing.T) (any, error) {
opts := NewRoutePolicyListOptions()
opts.SpaceGUIDs = Filter{
Values: []string{"33d27af8-788d-4de5-8f37-fb80d517f2ed"},
}
policies, _, err := c.RoutePolicies.List(context.Background(), opts)
return policies, err
},
},
{
Description: "List route policies with filter by source GUID",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
QueryString: "page=1&per_page=50&source_guids=1cb006ee-fb05-47e1-b541-c34179ddc446",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: g.Array(routePolicy),
Action: func(c *Client, t *testing.T) (any, error) {
opts := NewRoutePolicyListOptions()
opts.SourceGUIDs = Filter{
Values: []string{"1cb006ee-fb05-47e1-b541-c34179ddc446"},
}
policies, _, err := c.RoutePolicies.List(context.Background(), opts)
return policies, err
},
},
{
Description: "List route policies with filter by source",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
QueryString: "page=1&per_page=50&sources=network_policy",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: g.Array(routePolicy),
Action: func(c *Client, t *testing.T) (any, error) {
opts := NewRoutePolicyListOptions()
opts.Sources = Filter{
Values: []string{"network_policy"},
}
policies, _, err := c.RoutePolicies.List(context.Background(), opts)
return policies, err
},
},
{
Description: "List route policies with filter by organization GUID",
Route: testutil.MockRoute{
Method: "GET",
Endpoint: "/v3/route_policies",
QueryString: "organization_guids=3a5f687b-2ce8-4ade-be75-8eca99b0db8b&page=1&per_page=50",
Output: g.SinglePaged(routePolicy),
Status: http.StatusOK,
},
Expected: g.Array(routePolicy),
Action: func(c *Client, t *testing.T) (any, error) {
opts := NewRoutePolicyListOptions()
opts.OrganizationGUIDs = Filter{
Values: []string{"3a5f687b-2ce8-4ade-be75-8eca99b0db8b"},
}
policies, _, err := c.RoutePolicies.List(context.Background(), opts)
return policies, err
},
},
}
ExecuteTests(tests, t)
}
Loading