Skip to content

Commit

Permalink
LBAAS-142: add lbaas/v2 bindings
Browse files Browse the repository at this point in the history
  • Loading branch information
Mario Schäfer committed Oct 30, 2023
1 parent 00237d6 commit fe7dbdd
Show file tree
Hide file tree
Showing 11 changed files with 529 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ Some examples, more below in the actual changelog (newer entries are more likely
### Added
* core/v1: add `created_at` and `updated_at` fields to Resource type
* generic client: make common.PartialResource filterable
* lbaas/v2: added new `Cluster`, `Node` & `LoadBalancer` resources (#309, @anx-mschaefer)

## [0.5.3] - 2023-06-16

Expand Down
55 changes: 55 additions & 0 deletions pkg/apis/common/gs/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ package gs
import (
"bytes"
"context"
"go.anx.io/go-anxcloud/pkg/utils/object/filter"
"io"
"net/http"
"net/url"

"go.anx.io/go-anxcloud/pkg/api/types"
)
Expand All @@ -30,3 +32,56 @@ func (gs *GenericService) FilterAPIResponse(ctx context.Context, res *http.Respo
}
return res, nil
}

// CommonRequestBody is used to optionally omit the `State` field on create and update
// by embedding it to the request in the FilterAPIRequestBody hook
type CommonRequestBody struct {
State string `json:"state,omitempty"`
}

// RequestBody prevents decoding of delete responses as they are not compatible with the
// objects type
func RequestBody(ctx context.Context, br func() interface{}) (interface{}, error) {
op, err := types.OperationFromContext(ctx)
if err != nil {
return nil, err
}

if op == types.OperationCreate || op == types.OperationUpdate {
response := br()

return response, nil
}

return nil, nil
}

// EndpointURL is a helper function which can be wrapped by API bindings to enable the filter helper
func EndpointURL(ctx context.Context, obj types.Object, resourcePath string) (*url.URL, error) {
op, err := types.OperationFromContext(ctx)
if err != nil {
return nil, err
}

u, err := url.Parse(resourcePath)
if err != nil {
return nil, err
}

if op == types.OperationList {
helper, err := filter.NewHelper(obj)
if err != nil {
return nil, err
}

filters := helper.BuildQuery().Encode()

if filters != "" {
query := u.Query()
query.Set("filters", filters)
u.RawQuery = query.Encode()
}
}

return u, nil
}
24 changes: 24 additions & 0 deletions pkg/apis/lbaas/v2/lb_cluster_genclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package v2

import (
"context"
"go.anx.io/go-anxcloud/pkg/apis/common/gs"
"net/url"
)

// FilterAPIRequestBody adds the CommonRequestBody
func (c *Cluster) FilterAPIRequestBody(ctx context.Context) (interface{}, error) {
return gs.RequestBody(ctx, func() interface{} {
return &struct {
gs.CommonRequestBody
Cluster
}{
Cluster: *c,
}
})
}

// EndpointURL returns the common URL for operations on the Cluster resource
func (c *Cluster) EndpointURL(ctx context.Context) (*url.URL, error) {
return gs.EndpointURL(ctx, c, "/api/LBaaSv2_DEV/v1/clusters.json")
}
26 changes: 26 additions & 0 deletions pkg/apis/lbaas/v2/lb_cluster_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package v2

import (
"go.anx.io/go-anxcloud/pkg/apis/common/gs"
)

type LoadBalancerImplementation string

const (
LoadBalancerImplementationHAProxy LoadBalancerImplementation = "haproxy"
)

// anxcloud:object

// Cluster holds the information of a load balancing cluster
type Cluster struct {
gs.GenericService
gs.HasState

Identifier string `json:"identifier,omitempty" anxcloud:"identifier"`
Name string `json:"name,omitempty"`
Implementation LoadBalancerImplementation `json:"implementation,omitempty"`
FrontendPrefixes *gs.PartialResourceList `json:"frontend_prefixes,omitempty"`
BackendPrefixes *gs.PartialResourceList `json:"backend_prefixes,omitempty"`
Replicas *int `json:"replicas,omitempty"`
}
24 changes: 24 additions & 0 deletions pkg/apis/lbaas/v2/lb_node_genclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package v2

import (
"context"
"go.anx.io/go-anxcloud/pkg/apis/common/gs"
"net/url"
)

// FilterAPIRequestBody adds the CommonRequestBody
func (n *Node) FilterAPIRequestBody(ctx context.Context) (interface{}, error) {
return gs.RequestBody(ctx, func() interface{} {
return &struct {
gs.CommonRequestBody
Node
}{
Node: *n,
}
})
}

// EndpointURL returns the common URL for operations on the Node resource
func (n *Node) EndpointURL(ctx context.Context) (*url.URL, error) {
return gs.EndpointURL(ctx, n, "/api/LBaaSv2_DEV/v1/nodes.json")
}
19 changes: 19 additions & 0 deletions pkg/apis/lbaas/v2/lb_node_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package v2

import (
"go.anx.io/go-anxcloud/pkg/apis/common"
"go.anx.io/go-anxcloud/pkg/apis/common/gs"
)

// anxcloud:object

// Node holds the information of a load balancing node within a Cluster
type Node struct {
gs.GenericService
gs.HasState

Identifier string `json:"identifier,omitempty" anxcloud:"identifier"`
Name string `json:"name,omitempty"`
VM *common.PartialResource `json:"vm,omitempty"`
Cluster *common.PartialResource `json:"cluster,omitempty" anxcloud:"filterable"`
}
24 changes: 24 additions & 0 deletions pkg/apis/lbaas/v2/load_balancer_genclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package v2

import (
"context"
"go.anx.io/go-anxcloud/pkg/apis/common/gs"
"net/url"
)

// FilterAPIRequestBody adds the CommonRequestBody
func (lb *LoadBalancer) FilterAPIRequestBody(ctx context.Context) (interface{}, error) {
return gs.RequestBody(ctx, func() interface{} {
return &struct {
gs.CommonRequestBody
LoadBalancer
}{
LoadBalancer: *lb,
}
})
}

// EndpointURL returns the common URL for operations on LoadBalancer resource
func (lb *LoadBalancer) EndpointURL(ctx context.Context) (*url.URL, error) {
return gs.EndpointURL(ctx, lb, "/api/LBaaSv2_DEV/v1/load_balancers.json")
}
105 changes: 105 additions & 0 deletions pkg/apis/lbaas/v2/load_balancer_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package v2

import (
"encoding/json"

"go.anx.io/go-anxcloud/pkg/apis/common"
"go.anx.io/go-anxcloud/pkg/apis/common/gs"
"go.anx.io/go-anxcloud/pkg/utils/pointer"
)

// anxcloud:object

// LoadBalancer holds the information of a load balancing configuration within a Cluster
type LoadBalancer struct {
gs.GenericService
gs.HasState

Identifier string `json:"identifier,omitempty" anxcloud:"identifier"`
Name string `json:"name,omitempty"`
Generation int `json:"generation,omitempty"`
Cluster *common.PartialResource `json:"cluster,omitempty" anxcloud:"filterable"`
FrontendIPs *gs.PartialResourceList `json:"frontend_ips,omitempty"`
SSLCertificates *gs.PartialResourceList `json:"ssl_certificates,omitempty"`
RawDefinition *string `json:"definition,omitempty"`
}

// GetDefinition handles double json decoding.
// The API will likely allow nested json in the future.
func (lb *LoadBalancer) GetDefinition() (def Definition, err error) {
err = json.Unmarshal([]byte(*lb.RawDefinition), &def)
return
}

// SetDefinition handles double json encoding.
// The API will likely allow nested json in the future.
func (lb *LoadBalancer) SetDefinition(def *Definition) (err error) {
var rawDef []byte
rawDef, err = json.Marshal(def)
lb.RawDefinition = pointer.String(string(rawDef))
return
}

type FrontendProtocol string

const (
FrontendProtocolTCP FrontendProtocol = "TCP"
)

type BackendProtocol string

const (
BackendProtocolTCP BackendProtocol = "TCP"
BackendProtocolPROXY BackendProtocol = "PROXY"
)

type Definition struct {
Frontends []Frontend `json:"frontends,omitempty"`
Backends []Backend `json:"backends,omitempty"`
}

// Define ports and protocols exposed to the public side of the Load Balancer
type Frontend struct {
// Name of the Frontend
Name string `json:"name"`
// Frontend service protocol
Protocol FrontendProtocol `json:"protocol"`
// Configure frontend - backend relation
Backend FrontendBackend `json:"backend,omitempty"`
// TCP specific frontend configuration
TCP *FrontendTCP `json:"tcp,omitempty"`
}

// TCP specific frontend configuration
type FrontendTCP struct {
// Port for the frontend to listen to
Port uint16 `json:"port,omitempty"`
}

// Configure frontend - backend relation
type FrontendBackend struct {
// Backend service protocol
Protocol BackendProtocol `json:"protocol"`
// TCP specific backend configuration
TCP *FrontendBackendTCP `json:"tcp,omitempty"`
}

// TCP specific backend configuration
type FrontendBackendTCP struct {
Port uint16 `json:"port"`
}

// Define backend services and connect them to frontends
type Backend struct {
// Name of the Backend
Name string `json:"name"`
// IP addresses of the backend service
IPs []string `json:"ips,omitempty"`
// List of frontends connected to the backend
Frontends []BackendFrontend `json:"frontends,omitempty"`
}

type BackendFrontend struct {
// Name of the frontend to be connected to the backend
Name string `json:"name"`
}
Loading

0 comments on commit fe7dbdd

Please sign in to comment.