diff --git a/client/client.go b/client/client.go index a3d8d3e..ac0a888 100644 --- a/client/client.go +++ b/client/client.go @@ -46,6 +46,7 @@ type Client struct { Roles *RoleClient Root *RootClient Routes *RouteClient + RoutePolicies *RoutePolicyClient SecurityGroups *SecurityGroupClient ServiceBrokers *ServiceBrokerClient ServiceCredentialBindings *ServiceCredentialBindingClient @@ -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) diff --git a/client/route_policy.go b/client/route_policy.go new file mode 100644 index 0000000..255cb45 --- /dev/null +++ b/client/route_policy.go @@ -0,0 +1,226 @@ +package client + +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 + + GUIDs Filter `qs:"guids"` + RouteGUIDs Filter `qs:"route_guids"` + SpaceGUIDs Filter `qs:"space_guids"` + SourceGUIDs Filter `qs:"source_guids"` + Sources Filter `qs:"sources"` + OrganizationGUIDs Filter `qs:"organization_guids"` + Include resource.RoutePolicyIncludeType `qs:"include"` +} + +// 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 +} + +// 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 +} + +// GetIncludeRoute retrieves the specified route policy and include the associated route +func (c *RoutePolicyClient) GetIncludeRoute(ctx context.Context, guid string) (*resource.RoutePolicy, *resource.Route, error) { + var res resource.RoutePolicyList + err := c.client.get(ctx, path.Format("/v3/route_policies/%s?include=%s", guid, resource.RoutePolicyIncludeRoute), &res) + if err != nil { + return nil, nil, err + } + if len(res.Resources) == 0 { + return nil, nil, err + } + var route *resource.Route + if res.Included != nil && len(res.Included.Routes) > 0 { + route = res.Included.Routes[0] + } + return res.Resources[0], route, nil +} + +// GetIncludeSource retrieves the specified route policy and include the associated source app +func (c *RoutePolicyClient) GetIncludeSource(ctx context.Context, guid string) (*resource.RoutePolicy, *resource.App, error) { + var res resource.RoutePolicyList + err := c.client.get(ctx, path.Format("/v3/route_policies/%s?include=%s", guid, resource.RoutePolicyIncludeSource), &res) + if err != nil { + return nil, nil, err + } + if len(res.Resources) == 0 { + return nil, nil, err + } + var app *resource.App + if res.Included != nil && len(res.Included.Apps) > 0 { + app = res.Included.Apps[0] + } + return res.Resources[0], app, 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() + } + opts.Include = resource.RoutePolicyIncludeNone + + 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) + }) +} + +// ListIncludeRoute page all route policies the user has access to and include the associated routes +func (c *RoutePolicyClient) ListIncludeRoute(ctx context.Context, opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, []*resource.Route, *Pager, error) { + if opts == nil { + opts = NewRoutePolicyListOptions() + } + opts.Include = resource.RoutePolicyIncludeRoute + + var res resource.RoutePolicyList + err := c.client.list(ctx, "/v3/route_policies", opts.ToQueryString, &res) + if err != nil { + return nil, nil, nil, err + } + pager := NewPager(res.Pagination) + return res.Resources, res.Included.Routes, pager, nil +} + +// ListIncludeRouteAll retrieves all route policies the user has access to and include the associated routes +func (c *RoutePolicyClient) ListIncludeRouteAll(ctx context.Context, opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, []*resource.Route, error) { + if opts == nil { + opts = NewRoutePolicyListOptions() + } + + var all []*resource.RoutePolicy + var allRoutes []*resource.Route + for { + page, routes, pager, err := c.ListIncludeRoute(ctx, opts) + if err != nil { + return nil, nil, err + } + all = append(all, page...) + allRoutes = append(allRoutes, routes...) + if !pager.HasNextPage() { + break + } + pager.NextPage(opts) + } + return all, allRoutes, nil +} + +// ListIncludeSource page all route policies the user has access to and include the associated source apps +func (c *RoutePolicyClient) ListIncludeSource(ctx context.Context, opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, []*resource.App, []*resource.Space, []*resource.Organization, *Pager, error) { + if opts == nil { + opts = NewRoutePolicyListOptions() + } + opts.Include = resource.RoutePolicyIncludeSource + + var res resource.RoutePolicyList + err := c.client.list(ctx, "/v3/route_policies", opts.ToQueryString, &res) + if err != nil { + return nil, nil, nil, nil, nil, err + } + pager := NewPager(res.Pagination) + return res.Resources, res.Included.Apps, res.Included.Spaces, res.Included.Organizations, pager, nil +} + +// ListIncludeSourceAll retrieves all route policies the user has access to and include the associated source apps +func (c *RoutePolicyClient) ListIncludeSourceAll(ctx context.Context, opts *RoutePolicyListOptions) ([]*resource.RoutePolicy, []*resource.App, []*resource.Space, []*resource.Organization, error) { + if opts == nil { + opts = NewRoutePolicyListOptions() + } + + var all []*resource.RoutePolicy + var allApps []*resource.App + var allSpaces []*resource.Space + var allOrganizations []*resource.Organization + for { + page, apps, spaces, orgs, pager, err := c.ListIncludeSource(ctx, opts) + if err != nil { + return nil, nil, nil, nil, err + } + all = append(all, page...) + allApps = append(allApps, apps...) + allSpaces = append(allSpaces, spaces...) + allOrganizations = append(allOrganizations, orgs...) + if !pager.HasNextPage() { + break + } + pager.NextPage(opts) + } + return all, allApps, allSpaces, allOrganizations, nil +} + +// 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) + }) +} + +// Update the specified attributes of the route policy +func (c *RoutePolicyClient) Update(ctx context.Context, guid string, r *resource.RoutePolicyUpdate) (*resource.RoutePolicy, error) { + var routePolicy resource.RoutePolicy + _, err := c.client.patch(ctx, path.Format("/v3/route_policies/%s", guid), r, &routePolicy) + if err != nil { + return nil, err + } + return &routePolicy, nil +} diff --git a/client/route_policy_test.go b/client/route_policy_test.go new file mode 100644 index 0000000..5f83d19 --- /dev/null +++ b/client/route_policy_test.go @@ -0,0 +1,390 @@ +package client + +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 + route1 := g.Route().JSON + route2 := g.Route().JSON + app1 := g.Application().JSON + app2 := g.Application().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: "Get route policy with include route", + Route: testutil.MockRoute{ + Method: "GET", + Endpoint: "/v3/route_policies/c8dcf27f-39a3-466a-9cbf-1d3c31a43b93", + Output: g.PagedWithInclude( + testutil.PagedResult{ + Resources: []string{routePolicy}, + Routes: []string{route1}, + }), + Status: http.StatusOK, + }, + Expected: routePolicy, + Expected2: route1, + Action2: func(c *Client, t *testing.T) (any, any, error) { + return c.RoutePolicies.GetIncludeRoute(context.Background(), "c8dcf27f-39a3-466a-9cbf-1d3c31a43b93") + }, + }, + { + Description: "Get route policy with include source", + Route: testutil.MockRoute{ + Method: "GET", + Endpoint: "/v3/route_policies/c8dcf27f-39a3-466a-9cbf-1d3c31a43b93", + Output: g.PagedWithInclude( + testutil.PagedResult{ + Resources: []string{routePolicy}, + Apps: []string{app1}, + }), + Status: http.StatusOK, + }, + Expected: routePolicy, + Expected2: app1, + Action2: func(c *Client, t *testing.T) (any, any, error) { + return c.RoutePolicies.GetIncludeSource(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 + }, + }, + { + Description: "List route policies with include route", + 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.ListIncludeRoute(context.Background(), NewRoutePolicyListOptions()) + return policies, err + }, + }, + { + Description: "List all route policies with include route", + Route: testutil.MockRoute{ + Method: "GET", + Endpoint: "/v3/route_policies", + Output: g.PagedWithInclude( + testutil.PagedResult{ + Resources: []string{routePolicy, routePolicy2}, + Routes: []string{route1, route2}, + }), + Status: http.StatusOK, + }, + Expected: g.Array(routePolicy, routePolicy2), + Expected2: g.Array(route1, route2), + Action2: func(c *Client, t *testing.T) (any, any, error) { + return c.RoutePolicies.ListIncludeRouteAll(context.Background(), nil) + }, + }, + { + Description: "List route policies with include source", + 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.ListIncludeSource(context.Background(), NewRoutePolicyListOptions()) + return policies, err + }, + }, + { + Description: "List all route policies with include source", + Route: testutil.MockRoute{ + Method: "GET", + Endpoint: "/v3/route_policies", + Output: g.PagedWithInclude( + testutil.PagedResult{ + Resources: []string{routePolicy, routePolicy2}, + Apps: []string{app1, app2}, + }), + Status: http.StatusOK, + }, + Expected: g.Array(routePolicy, routePolicy2), + Expected2: g.Array(app1, app2), + Action4: func(c *Client, t *testing.T) (any, any, any, any, error) { + return c.RoutePolicies.ListIncludeSourceAll(context.Background(), nil) + }, + }, + { + Description: "Update route policy", + Route: testutil.MockRoute{ + Method: "PATCH", + Endpoint: "/v3/route_policies/c8dcf27f-39a3-466a-9cbf-1d3c31a43b93", + Output: g.Single(routePolicy), + Status: http.StatusOK, + PostForm: `{ "metadata": { "labels": {"key": "value"}, "annotations": {"note": "detailed information"}}}`, + }, + Expected: routePolicy, + Action: func(c *Client, t *testing.T) (any, error) { + r := &resource.RoutePolicyUpdate{ + Metadata: resource.NewMetadata(). + WithLabel("", "key", "value"). + WithAnnotation("", "note", "detailed information"), + } + return c.RoutePolicies.Update(context.Background(), "c8dcf27f-39a3-466a-9cbf-1d3c31a43b93", r) + }, + }, + } + ExecuteTests(tests, t) +} diff --git a/client/test_runner.go b/client/test_runner.go index 067f67d..9de3478 100644 --- a/client/test_runner.go +++ b/client/test_runner.go @@ -21,6 +21,7 @@ type RouteTest struct { Action func(c *Client, t *testing.T) (any, error) Action2 func(c *Client, t *testing.T) (any, any, error) Action3 func(c *Client, t *testing.T) (any, any, any, error) + Action4 func(c *Client, t *testing.T) (any, any, any, any, error) } func ExecuteTests(tests []RouteTest, t *testing.T) { diff --git a/resource/route_policy.go b/resource/route_policy.go new file mode 100644 index 0000000..782b0ac --- /dev/null +++ b/resource/route_policy.go @@ -0,0 +1,65 @@ +package resource + +type RoutePolicy struct { + Source string `json:"source"` + Metadata *Metadata `json:"metadata"` + Relationships RoutePolicyRelationships `json:"relationships"` + Resource `json:",inline"` +} + +type RoutePolicyCreate struct { + Relationships RoutePolicyRelationships `json:"relationships"` + Source string `json:"source"` +} + +type RoutePolicyUpdate struct { + Metadata *Metadata `json:"metadata,omitempty"` +} + +type RoutePolicyList struct { + Pagination Pagination `json:"pagination"` + Resources []*RoutePolicy `json:"resources"` + Included *RoutePolicyIncluded `json:"included"` +} + +type RoutePolicyRelationships struct { + Route *ToOneRelationship `json:"route,omitempty"` + App *ToOneRelationship `json:"app,omitempty"` + Space *ToOneRelationship `json:"space,omitempty"` + Organization *ToOneRelationship `json:"organization,omitempty"` +} + +type RoutePolicyWithIncluded struct { + RoutePolicy RoutePolicy `json:"route_policy"` + Included *RoutePolicyIncluded `json:"included"` +} + +type RoutePolicyIncluded struct { + Routes []*Route `json:"routes"` + Apps []*App `json:"apps"` + Spaces []*Space `json:"spaces"` + Organizations []*Organization `json:"organizations"` +} + +// RoutePolicyIncludeType https://v3-apidocs.cloudfoundry.org/version/3.126.0/index.html#include +type RoutePolicyIncludeType int + +const ( + RoutePolicyIncludeNone RoutePolicyIncludeType = iota + RoutePolicyIncludeRoute + RoutePolicyIncludeSource + RoutePolicyIncludeRouteSource +) + +func (r RoutePolicyIncludeType) String() string { + switch r { + case RoutePolicyIncludeRoute: + return "route" + case RoutePolicyIncludeSource: + return "source" + case RoutePolicyIncludeRouteSource: + return "route,source" + default: + return "" + } +} diff --git a/testutil/object_generator.go b/testutil/object_generator.go index 76baf9d..5836abe 100644 --- a/testutil/object_generator.go +++ b/testutil/object_generator.go @@ -343,6 +343,13 @@ func (o ObjectJSONGenerator) RouteDestinationWithLinks() *JSONResource { return o.renderTemplate(r, "route_destination_with_links.json") } +func (o ObjectJSONGenerator) RoutePolicy() *JSONResource { + r := &JSONResource{ + GUID: RandomGUID(), + } + return o.renderTemplate(r, "route_policy.json") +} + func (o ObjectJSONGenerator) ServiceBroker() *JSONResource { r := &JSONResource{ GUID: RandomGUID(), diff --git a/testutil/template/route_policy.json b/testutil/template/route_policy.json new file mode 100644 index 0000000..ae7ffb8 --- /dev/null +++ b/testutil/template/route_policy.json @@ -0,0 +1,38 @@ +{ + "guid": "{{.GUID}}", + "source": "1cb006ee-fb05-47e1-b541-c34179ddc446", + "created_at": "2023-01-01T00:00:00Z", + "updated_at": "2023-01-01T00:00:00Z", + "metadata": { + "labels": {}, + "annotations": {} + }, + "relationships": { + "route": { + "data": { + "guid": "5a85c020-3e3d-42a5-a475-5084c5357e82" + } + }, + "app": { + "data": { + "guid": "1cb006ee-fb05-47e1-b541-c34179ddc446" + } + }, + "space": { + "data": { + "guid": "33d27af8-788d-4de5-8f37-fb80d517f2ed" + } + }, + "organization": { + "data": { + "guid": "3a5f687b-2ce8-4ade-be75-8eca99b0db8b" + } + } + }, + "links": { + "self": { + "href": "https://api.example.org/v3/route_policies/{{.GUID}}" + } + } +} +