Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move generic client APIs into pkg/apis/ #86

Merged
merged 1 commit into from
Nov 29, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
30 changes: 14 additions & 16 deletions pkg/api/api_examples_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import (
"fmt"
"log"

lbaasv1 "github.com/anexia-it/go-anxcloud/pkg/apis/lbaas/v1"
"github.com/anexia-it/go-anxcloud/pkg/client"
"github.com/anexia-it/go-anxcloud/pkg/lbaas/backend"
lbaasCommon "github.com/anexia-it/go-anxcloud/pkg/lbaas/common"
"github.com/anexia-it/go-anxcloud/pkg/lbaas/loadbalancer"

"github.com/anexia-it/go-anxcloud/pkg/api/types"
)
Expand All @@ -23,7 +21,7 @@ func ExampleNewAPI() {
log.Fatalf("Error creating api instance: %v\n", err)
} else {
// do something with api
lb := loadbalancer.Loadbalancer{Identifier: "bogus identifier"}
lb := lbaasv1.LoadBalancer{Identifier: "bogus identifier"}
if err := api.Get(context.TODO(), &lb); IgnoreNotFound(err) != nil {
fmt.Printf("Error retrieving loadbalancer with identifier '%v'\n", lb.Identifier)
}
Expand All @@ -39,14 +37,14 @@ func Example_usage() {
apiClient := newExampleAPI()

// retrieve and create backend, handling errors along the way.
backend := backend.Backend{Identifier: "bogus identifier 1"}
backend := lbaasv1.Backend{Identifier: "bogus identifier 1"}
if err := apiClient.Get(context.TODO(), &backend); IgnoreNotFound(err) != nil {
fmt.Printf("Fatal error while retrieving backend: %v\n", err)
} else if err != nil {
fmt.Printf("Backend not yet existing, creating ...\n")

backend.Name = "backend-01"
backend.Mode = lbaasCommon.HTTP
backend.Mode = lbaasv1.HTTP
// [...]

if err := apiClient.Create(context.TODO(), &backend); err != nil {
Expand All @@ -70,9 +68,9 @@ func ExampleAPI_create() {
// see example on NewAPI how to implement this function
apiClient := newExampleAPI()

backend := backend.Backend{
backend := lbaasv1.Backend{
Name: "backend-01",
Mode: lbaasCommon.HTTP,
Mode: lbaasv1.HTTP,
// [...]
}

Expand All @@ -89,7 +87,7 @@ func ExampleAPI_destroy() {
// see example on NewAPI how to implement this function
apiClient := newExampleAPI()

backend := backend.Backend{Identifier: "bogus identifier 1"}
backend := lbaasv1.Backend{Identifier: "bogus identifier 1"}
if err := apiClient.Destroy(context.TODO(), &backend); err != nil {
fmt.Printf("Error destroying backend: %v\n", err)
} else {
Expand All @@ -103,7 +101,7 @@ func ExampleAPI_get() {
// see example on NewAPI how to implement this function
apiClient := newExampleAPI()

backend := backend.Backend{Identifier: "bogus identifier 1"}
backend := lbaasv1.Backend{Identifier: "bogus identifier 1"}
if err := apiClient.Get(context.TODO(), &backend); err != nil {
fmt.Printf("Error retrieving backend: %v\n", err)
} else {
Expand All @@ -121,12 +119,12 @@ func ExampleAPI_listPaged() {

// Beware: listing endpoints usually do not return all data for an object, sometimes
// only the identifier is filled. This varies by specific API.
b := backend.Backend{}
b := lbaasv1.Backend{}
var pageIter types.PageInfo
if err := apiClient.List(context.TODO(), &b, Paged(1, 2, &pageIter)); err != nil {
fmt.Printf("Error listing backends: %v\n", err)
} else {
var backends []backend.Backend
var backends []lbaasv1.Backend
for pageIter.Next(&backends) {
fmt.Printf("Listing entries on page %v\n", pageIter.CurrentPage())

Expand Down Expand Up @@ -168,7 +166,7 @@ func ExampleAPI_listChannel() {

// Beware: listing endpoints usually do not return all data for an object, sometimes
// only the identifier is filled. This varies by specific API.
b := backend.Backend{LoadBalancer: loadbalancer.LoadBalancerInfo{Identifier: "bogus identifier 2"}}
b := lbaasv1.Backend{LoadBalancer: lbaasv1.LoadBalancer{Identifier: "bogus identifier 2"}}
if err := apiClient.List(context.TODO(), &b, ObjectChannel(&channel)); err != nil {
fmt.Printf("Error listing backends: %v\n", err)
} else {
Expand All @@ -192,10 +190,10 @@ func ExampleAPI_update() {
// see example on NewAPI how to implement this function
apiClient := newExampleAPI()

b := backend.Backend{
b := lbaasv1.Backend{
Identifier: "bogus identifier 1",
Name: "Updated backend",
Mode: lbaasCommon.HTTP,
Mode: lbaasv1.HTTP,
// [...]
}

Expand All @@ -204,7 +202,7 @@ func ExampleAPI_update() {
} else {
fmt.Printf("Successfully updated backend\n")

retrieved := backend.Backend{Identifier: "bogus identifier 1"}
retrieved := lbaasv1.Backend{Identifier: "bogus identifier 1"}
if err := apiClient.Get(context.TODO(), &retrieved); err != nil {
fmt.Printf("Error verifying updated backend: %v\n", err)
} else {
Expand Down
42 changes: 23 additions & 19 deletions pkg/api/mockserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package api

import (
"encoding/json"
"fmt"
"net/http"
"net/url"
"path"
Expand All @@ -10,9 +11,8 @@ import (

"github.com/onsi/gomega/ghttp"

lbaasv1 "github.com/anexia-it/go-anxcloud/pkg/apis/lbaas/v1"
"github.com/anexia-it/go-anxcloud/pkg/lbaas/backend"
lbaasCommon "github.com/anexia-it/go-anxcloud/pkg/lbaas/common"
"github.com/anexia-it/go-anxcloud/pkg/lbaas/loadbalancer"
)

func newMockServer() *ghttp.Server {
Expand Down Expand Up @@ -43,45 +43,44 @@ func newMockServer() *ghttp.Server {

server := ghttp.NewServer()
server.SetAllowUnhandledRequests(true)
server.SetUnhandledRequestStatusCode(500)

backends := []backend.Backend{
backends := []lbaasv1.Backend{
{
Name: "Example-Backend",
Identifier: "bogus identifier 1",
Mode: lbaasCommon.TCP,
LoadBalancer: loadbalancer.LoadBalancerInfo{
Mode: lbaasv1.TCP,
LoadBalancer: lbaasv1.LoadBalancer{
Identifier: "bogus identifier 2",
},
},
{
Name: "backend-01",
Identifier: "bogus identifier 3",
Mode: lbaasCommon.TCP,
Mode: lbaasv1.TCP,
},
{
Name: "test-backend-01",
Identifier: "test identifier 1",
Mode: lbaasCommon.TCP,
Mode: lbaasv1.TCP,
},
{
Name: "test-backend-02",
Identifier: "test identifier 2",
Mode: lbaasCommon.TCP,
LoadBalancer: loadbalancer.LoadBalancerInfo{
Mode: lbaasv1.TCP,
LoadBalancer: lbaasv1.LoadBalancer{
Identifier: "bogus identifier 2",
},
},
{
Name: "test-backend-03",
Identifier: "test identifier 3",
Mode: lbaasCommon.TCP,
Mode: lbaasv1.TCP,
},
{
Name: "test-backend-04",
Identifier: "test identifier 4",
Mode: lbaasCommon.TCP,
LoadBalancer: loadbalancer.LoadBalancerInfo{
Mode: lbaasv1.TCP,
LoadBalancer: lbaasv1.LoadBalancer{
Identifier: "bogus identifier 2",
},
},
Expand Down Expand Up @@ -158,7 +157,7 @@ func newMockServer() *ghttp.Server {
backend.Backend{
Name: "backend-01",
Identifier: "generated identifier " + strconv.Itoa(identifierGenerateCounter),
Mode: lbaasCommon.TCP,
Mode: lbaasv1.TCP,
},
)

Expand All @@ -182,13 +181,17 @@ func newMockServer() *ghttp.Server {

server.RouteToHandler("PUT", singleBackendPath, func(res http.ResponseWriter, req *http.Request) {
if req.Header.Get("content-type") != "application/json; charset=utf-8" {
errorResponse(505, "Content-Type header on request not set", res)
errorResponse(500, "Content-Type header on request not set", res)
return
}

update := backend.Backend{}
update := struct {
lbaasv1.Backend
LoadBalancer string `json:"load_balancer"`
}{}
if err := json.NewDecoder(req.Body).Decode(&update); err != nil {
errorResponse(505, "Invalid request body", res)
fmt.Printf("Invalid request body: %v\n", err)
errorResponse(500, fmt.Sprintf("invalid request body: %v", err), res)
return
}

Expand All @@ -199,7 +202,8 @@ func newMockServer() *ghttp.Server {

for _, b := range backends {
if b.Identifier == identifier {
newBackends = append(newBackends, update)
update.Backend.LoadBalancer.Identifier = update.LoadBalancer
newBackends = append(newBackends, update.Backend)
found = true
} else {
newBackends = append(newBackends, b)
Expand All @@ -212,7 +216,7 @@ func newMockServer() *ghttp.Server {
errorResponse(404, "", res)
} else {
res.Header().Add("Content-Type", "application/json; charset=utf-8")
_ = json.NewEncoder(res).Encode(update)
_ = json.NewEncoder(res).Encode(update.Backend)
}
})

Expand Down
42 changes: 42 additions & 0 deletions pkg/apis/core/v1/resource_genclient.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package v1

import (
"context"
"net/url"

"github.com/anexia-it/go-anxcloud/pkg/api"
"github.com/anexia-it/go-anxcloud/pkg/api/types"
"github.com/go-logr/logr"
)

func (i Info) EndpointURL(ctx context.Context) (*url.URL, error) {
u, err := url.ParseRequestURI("/api/core/v1/resource.json")
if err != nil {
return nil, err
}

op, err := types.OperationFromContext(ctx)
if err != nil {
return nil, err
}
switch op {
// OperationCreate is not supported because the API does not exist in the engine.
// OperationDestroy and OperationUpdate is not yet implemented
case types.OperationCreate, types.OperationDestroy, types.OperationUpdate:
return nil, api.ErrOperationNotSupported
}

if op == types.OperationList {
query := u.Query()

if len(i.Tags) > 1 {
logr.FromContextOrDiscard(ctx).Info("Listing with multiple tags isn't supported. Only first one used")
}

if len(i.Tags) > 0 {
query.Add("tag_name", i.Tags[0])
}
u.RawQuery = query.Encode()
}
return u, err
}
17 changes: 17 additions & 0 deletions pkg/apis/core/v1/resource_types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package v1

// Type is part of info.
type Type struct {
Identifier string `json:"identifier"`
Name string `json:"name"`
}

// anxcloud:object

// Info contains all information about a resource.
type Info struct {
Identifier string `json:"identifier" anxcloud:"identifier"`
Name string `json:"name"`
Type Type `json:"resource_type"`
Tags []string `json:"tags"`
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package loadbalancer
package v1

import (
"testing"
Expand All @@ -7,7 +7,7 @@ import (
. "github.com/onsi/gomega"
)

func TestLoadbalancer(t *testing.T) {
func TestCore(t *testing.T) {
RegisterFailHandler(Fail)
RunSpecs(t, "test suite for Loadbalancer")
RunSpecs(t, "test suite for core API definition")
}
17 changes: 17 additions & 0 deletions pkg/apis/core/v1/xxgenerated_object_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package v1

import (
. "github.com/anexia-it/go-anxcloud/pkg/utils/test/gomega"
. "github.com/onsi/ginkgo"
. "github.com/onsi/gomega"

"github.com/anexia-it/go-anxcloud/pkg/api/types"
)

var _ = Describe("Object Info", func() {
It("implements the interface types.Object", func() {
var i types.Object
o := Info{}
Expect(&o).To(ImplementInterface(&i))
})
})