Add controller API client interface (#1467)

This PR adds an interface for controller API client, it allows us to
implement mock API client for unit testing with ease and we are
able to generate spec file without accessing the real Fission server.
This commit is contained in:
Ta-Ching Chen
2019-12-16 23:14:14 +08:00
committed by GitHub
parent 01bdc5bf89
commit bfbb80efcf
71 changed files with 1021 additions and 1025 deletions
+51 -46
View File
@@ -34,11 +34,13 @@ import (
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
"github.com/fission/fission/pkg/controller/client"
"github.com/fission/fission/pkg/controller/client/rest"
ferror "github.com/fission/fission/pkg/error"
"github.com/fission/fission/pkg/fission-cli/cmd"
)
var g struct {
client *client.Client
cmd.CommandActioner
}
func panicIf(err error) {
@@ -96,38 +98,38 @@ func TestFunctionApi(t *testing.T) {
},
},
}
_, err := g.client.FunctionGet(&metav1.ObjectMeta{
_, err := g.Client().V1().Function().Get(&metav1.ObjectMeta{
Name: testFunc.Metadata.Name,
Namespace: metav1.NamespaceDefault,
})
assertNotFoundFailure(err, "function")
m, err := g.client.FunctionCreate(testFunc)
m, err := g.Client().V1().Function().Create(testFunc)
panicIf(err)
defer func() {
err := g.client.FunctionDelete(m)
err := g.Client().V1().Function().Delete(m)
panicIf(err)
}()
_, err = g.client.FunctionCreate(testFunc)
_, err = g.Client().V1().Function().Create(testFunc)
assertNameReuseFailure(err, "function")
testFunc.Metadata.ResourceVersion = m.ResourceVersion
testFunc.Spec.Package.FunctionName = "yyy"
_, err = g.client.FunctionUpdate(testFunc)
_, err = g.Client().V1().Function().Update(testFunc)
panicIf(err)
testFunc.Metadata.ResourceVersion = ""
testFunc.Metadata.Name = "bar"
m2, err := g.client.FunctionCreate(testFunc)
m2, err := g.Client().V1().Function().Create(testFunc)
panicIf(err)
defer g.client.FunctionDelete(m2)
defer g.Client().V1().Function().Delete(m2)
funcs, err := g.client.FunctionList(metav1.NamespaceDefault)
funcs, err := g.Client().V1().Function().List(metav1.NamespaceDefault)
panicIf(err)
assert(len(funcs) == 2, fmt.Sprintf("created two functions, but found %v", len(funcs)))
funcs_url := g.client.Url + "/v2/functions"
funcs_url := g.Client().ServerURL() + "/v2/functions"
resp, err := http.Get(funcs_url)
panicIf(err)
defer resp.Body.Close()
@@ -157,20 +159,20 @@ func TestHTTPTriggerApi(t *testing.T) {
},
},
}
_, err := g.client.HTTPTriggerGet(&metav1.ObjectMeta{
_, err := g.Client().V1().HTTPTrigger().Get(&metav1.ObjectMeta{
Name: testTrigger.Metadata.Name,
Namespace: metav1.NamespaceDefault,
})
assertNotFoundFailure(err, "httptrigger")
m, err := g.client.HTTPTriggerCreate(testTrigger)
m, err := g.Client().V1().HTTPTrigger().Create(testTrigger)
panicIf(err)
defer g.client.HTTPTriggerDelete(m)
defer g.Client().V1().HTTPTrigger().Delete(m)
_, err = g.client.HTTPTriggerCreate(testTrigger)
_, err = g.Client().V1().HTTPTrigger().Create(testTrigger)
assertNameReuseFailure(err, "httptrigger")
tr, err := g.client.HTTPTriggerGet(m)
tr, err := g.Client().V1().HTTPTrigger().Get(m)
panicIf(err)
assert(testTrigger.Spec.Method == tr.Spec.Method &&
testTrigger.Spec.RelativeURL == tr.Spec.RelativeURL &&
@@ -179,20 +181,20 @@ func TestHTTPTriggerApi(t *testing.T) {
testTrigger.Metadata.ResourceVersion = m.ResourceVersion
testTrigger.Spec.RelativeURL = "/hi"
_, err = g.client.HTTPTriggerUpdate(testTrigger)
_, err = g.Client().V1().HTTPTrigger().Update(testTrigger)
panicIf(err)
testTrigger.Metadata.ResourceVersion = ""
testTrigger.Metadata.Name = "yyy"
_, err = g.client.HTTPTriggerCreate(testTrigger)
_, err = g.Client().V1().HTTPTrigger().Create(testTrigger)
assert(err != nil, "duplicate trigger should not be allowed")
testTrigger.Spec.RelativeURL = "/hi2"
m2, err := g.client.HTTPTriggerCreate(testTrigger)
m2, err := g.Client().V1().HTTPTrigger().Create(testTrigger)
panicIf(err)
defer g.client.HTTPTriggerDelete(m2)
defer g.Client().V1().HTTPTrigger().Delete(m2)
ts, err := g.client.HTTPTriggerList(metav1.NamespaceDefault)
ts, err := g.Client().V1().HTTPTrigger().List(metav1.NamespaceDefault)
panicIf(err)
assert(len(ts) == 2, fmt.Sprintf("created two triggers, but found %v", len(ts)))
}
@@ -212,36 +214,36 @@ func TestEnvironmentApi(t *testing.T) {
Resources: v1.ResourceRequirements{},
},
}
_, err := g.client.EnvironmentGet(&metav1.ObjectMeta{
_, err := g.Client().V1().Environment().Get(&metav1.ObjectMeta{
Name: testEnv.Metadata.Name,
Namespace: metav1.NamespaceDefault,
})
assertNotFoundFailure(err, "environment")
m, err := g.client.EnvironmentCreate(testEnv)
m, err := g.Client().V1().Environment().Create(testEnv)
panicIf(err)
defer g.client.EnvironmentDelete(m)
defer g.Client().V1().Environment().Delete(m)
_, err = g.client.EnvironmentCreate(testEnv)
_, err = g.Client().V1().Environment().Create(testEnv)
assertNameReuseFailure(err, "environment")
e, err := g.client.EnvironmentGet(m)
e, err := g.Client().V1().Environment().Get(m)
panicIf(err)
assert(reflect.DeepEqual(testEnv.Spec, e.Spec), "env should match after reading")
testEnv.Metadata.ResourceVersion = m.ResourceVersion
testEnv.Spec.Runtime.Image = "another-img"
_, err = g.client.EnvironmentUpdate(testEnv)
_, err = g.Client().V1().Environment().Update(testEnv)
panicIf(err)
testEnv.Metadata.ResourceVersion = ""
testEnv.Metadata.Name = "bar"
m2, err := g.client.EnvironmentCreate(testEnv)
m2, err := g.Client().V1().Environment().Create(testEnv)
panicIf(err)
defer g.client.EnvironmentDelete(m2)
defer g.Client().V1().Environment().Delete(m2)
ts, err := g.client.EnvironmentList(metav1.NamespaceDefault)
ts, err := g.Client().V1().Environment().List(metav1.NamespaceDefault)
panicIf(err)
assert(len(ts) == 2, fmt.Sprintf("created two envs, but found %v", len(ts)))
}
@@ -261,20 +263,20 @@ func TestWatchApi(t *testing.T) {
},
},
}
_, err := g.client.WatchGet(&metav1.ObjectMeta{
_, err := g.Client().V1().KubeWatcher().Get(&metav1.ObjectMeta{
Name: testWatch.Metadata.Name,
Namespace: metav1.NamespaceDefault,
})
assertNotFoundFailure(err, "watch")
m, err := g.client.WatchCreate(testWatch)
m, err := g.Client().V1().KubeWatcher().Create(testWatch)
panicIf(err)
defer g.client.WatchDelete(m)
defer g.Client().V1().KubeWatcher().Delete(m)
_, err = g.client.WatchCreate(testWatch)
_, err = g.Client().V1().KubeWatcher().Create(testWatch)
assertNameReuseFailure(err, "watch")
w, err := g.client.WatchGet(m)
w, err := g.Client().V1().KubeWatcher().Get(m)
panicIf(err)
assert(testWatch.Spec.Namespace == w.Spec.Namespace &&
testWatch.Spec.Type == w.Spec.Type &&
@@ -282,11 +284,11 @@ func TestWatchApi(t *testing.T) {
testWatch.Spec.FunctionReference.Name == w.Spec.FunctionReference.Name, "watch should match after reading")
testWatch.Metadata.Name = "yyy"
m2, err := g.client.WatchCreate(testWatch)
m2, err := g.Client().V1().KubeWatcher().Create(testWatch)
panicIf(err)
defer g.client.WatchDelete(m2)
defer g.Client().V1().KubeWatcher().Delete(m2)
ws, err := g.client.WatchList(metav1.NamespaceDefault)
ws, err := g.Client().V1().KubeWatcher().List(metav1.NamespaceDefault)
panicIf(err)
assert(len(ws) == 2, fmt.Sprintf("created two watches, but found %v", len(ws)))
}
@@ -305,17 +307,17 @@ func TestTimeTriggerApi(t *testing.T) {
},
},
}
_, err := g.client.TimeTriggerGet(&metav1.ObjectMeta{Name: testTrigger.Metadata.Name})
_, err := g.Client().V1().TimeTrigger().Get(&metav1.ObjectMeta{Name: testTrigger.Metadata.Name})
assertNotFoundFailure(err, "trigger")
m, err := g.client.TimeTriggerCreate(testTrigger)
m, err := g.Client().V1().TimeTrigger().Create(testTrigger)
panicIf(err)
defer g.client.TimeTriggerDelete(m)
defer g.Client().V1().TimeTrigger().Delete(m)
_, err = g.client.TimeTriggerCreate(testTrigger)
_, err = g.Client().V1().TimeTrigger().Create(testTrigger)
assertNameReuseFailure(err, "trigger")
tr, err := g.client.TimeTriggerGet(m)
tr, err := g.Client().V1().TimeTrigger().Get(m)
panicIf(err)
assert(testTrigger.Spec.Cron == tr.Spec.Cron &&
testTrigger.Spec.FunctionReference.Type == tr.Spec.FunctionReference.Type &&
@@ -323,16 +325,16 @@ func TestTimeTriggerApi(t *testing.T) {
testTrigger.Metadata.ResourceVersion = m.ResourceVersion
testTrigger.Spec.Cron = "@hourly"
_, err = g.client.TimeTriggerUpdate(testTrigger)
_, err = g.Client().V1().TimeTrigger().Update(testTrigger)
panicIf(err)
testTrigger.Metadata.ResourceVersion = ""
testTrigger.Metadata.Name = "yyy"
testTrigger.Spec.Cron = "Not valid cron spec"
_, err = g.client.TimeTriggerCreate(testTrigger)
_, err = g.Client().V1().TimeTrigger().Create(testTrigger)
assertCronSpecFails(err)
ts, err := g.client.TimeTriggerList(metav1.NamespaceDefault)
ts, err := g.Client().V1().TimeTrigger().List(metav1.NamespaceDefault)
panicIf(err)
assert(len(ts) == 1, fmt.Sprintf("created two time triggers, but found %v", len(ts)))
}
@@ -353,7 +355,10 @@ func TestMain(m *testing.M) {
go Start(logger, 8888, true)
time.Sleep(5 * time.Second)
g.client = client.MakeClient("http://localhost:8888")
restClient := rest.NewRESTClient("http://localhost:8888")
// TODO: use fake rest client for offline spec generation
cmd.SetClientset(client.MakeClientset(restClient))
resp, err := http.Get("http://localhost:8888/")
panicIf(err)
+18 -100
View File
@@ -17,115 +17,33 @@ limitations under the License.
package client
import (
"bytes"
"io"
"io/ioutil"
"net/http"
"strings"
"github.com/pkg/errors"
ferror "github.com/fission/fission/pkg/error"
)
var (
DefaultRequestHeaders map[string]string
"github.com/fission/fission/pkg/controller/client/rest"
v1 "github.com/fission/fission/pkg/controller/client/v1"
)
type (
Client struct {
Url string
Headers map[string]string
Interface interface {
V1() v1.V1Interface
ServerURL() string
}
Clientset struct {
restClient rest.Interface
v1 v1.V1Interface
}
)
func MakeClient(serverUrl string) *Client {
return &Client{
Url: strings.TrimSuffix(serverUrl, "/"),
Headers: DefaultRequestHeaders,
func MakeClientset(restClient rest.Interface) Interface {
return &Clientset{
restClient: restClient,
v1: v1.MakeV1Client(restClient),
}
}
func (c *Client) create(relativeUrl string, contentType string, payload []byte) (*http.Response, error) {
var reader io.Reader
if len(payload) > 0 {
reader = bytes.NewReader(payload)
}
return c.sendRequest(http.MethodPost, c.v2CrdUrl(relativeUrl), map[string]string{"Content-type": contentType}, reader)
func (c *Clientset) V1() v1.V1Interface {
return c.v1
}
func (c *Client) put(relativeUrl string, contentType string, payload []byte) (*http.Response, error) {
var reader io.Reader
if len(payload) > 0 {
reader = bytes.NewReader(payload)
}
return c.sendRequest(http.MethodPut, c.v2CrdUrl(relativeUrl), map[string]string{"Content-type": contentType}, reader)
}
func (c *Client) get(relativeUrl string) (*http.Response, error) {
return c.sendRequest(http.MethodGet, c.v2CrdUrl(relativeUrl), nil, nil)
}
func (c *Client) delete(relativeUrl string) error {
resp, err := c.sendRequest(http.MethodDelete, c.v2CrdUrl(relativeUrl), nil, nil)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.Wrap(err, "error deleting")
} else {
return errors.Errorf("failed to delete: %v", string(body))
}
}
return nil
}
func (c *Client) proxy(method string, relativeUrl string, payload []byte) (*http.Response, error) {
var reader io.Reader
if len(payload) > 0 {
reader = bytes.NewReader(payload)
}
return c.sendRequest(method, c.proxyUrl(relativeUrl), nil, reader)
}
func (c *Client) sendRequest(method string, relativeUrl string, headers map[string]string, reader io.Reader) (*http.Response, error) {
req, err := http.NewRequest(method, relativeUrl, reader)
if err != nil {
return nil, err
}
for _, hs := range []map[string]string{headers, c.Headers} {
for k, v := range hs {
req.Header.Set(k, v)
}
}
return http.DefaultClient.Do(req)
}
func (c *Client) v2CrdUrl(relativeUrl string) string {
return c.Url + "/v2/" + strings.TrimPrefix(relativeUrl, "/")
}
func (c *Client) proxyUrl(relativeUrl string) string {
return c.Url + "/proxy/" + strings.TrimPrefix(relativeUrl, "/")
}
func (c *Client) handleResponse(resp *http.Response) ([]byte, error) {
if resp.StatusCode != 200 {
return nil, ferror.MakeErrorFromHTTP(resp)
}
body, err := ioutil.ReadAll(resp.Body)
return body, err
}
func (c *Client) handleCreateResponse(resp *http.Response) ([]byte, error) {
if resp.StatusCode != 201 {
return nil, ferror.MakeErrorFromHTTP(resp)
}
body, err := ioutil.ReadAll(resp.Body)
return body, err
func (c *Clientset) ServerURL() string {
return c.restClient.ServerURL()
}
+126
View File
@@ -0,0 +1,126 @@
/*
Copyright 2019 The Fission Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package rest
import (
"bytes"
"context"
"io"
"io/ioutil"
"net/http"
"strings"
"github.com/pkg/errors"
"golang.org/x/net/context/ctxhttp"
)
type (
Interface interface {
Create(relativeUrl string, contentType string, payload []byte) (*http.Response, error)
Put(relativeUrl string, contentType string, payload []byte) (*http.Response, error)
Get(relativeUrl string) (*http.Response, error)
Delete(relativeUrl string) error
Proxy(method string, relativeUrl string, payload []byte) (*http.Response, error)
ServerInfo() (*http.Response, error)
ServerURL() string
}
RESTClient struct {
url string
}
)
func NewRESTClient(serverUrl string) Interface {
return &RESTClient{
url: strings.TrimSuffix(serverUrl, "/"),
}
}
func (c *RESTClient) Create(relativeUrl string, contentType string, payload []byte) (*http.Response, error) {
var reader io.Reader
if len(payload) > 0 {
reader = bytes.NewReader(payload)
}
return c.sendRequest(http.MethodPost, c.v2CrdUrl(relativeUrl), map[string]string{"Content-type": contentType}, reader)
}
func (c *RESTClient) Put(relativeUrl string, contentType string, payload []byte) (*http.Response, error) {
var reader io.Reader
if len(payload) > 0 {
reader = bytes.NewReader(payload)
}
return c.sendRequest(http.MethodPut, c.v2CrdUrl(relativeUrl), map[string]string{"Content-type": contentType}, reader)
}
func (c *RESTClient) Get(relativeUrl string) (*http.Response, error) {
return c.sendRequest(http.MethodGet, c.v2CrdUrl(relativeUrl), nil, nil)
}
func (c *RESTClient) Delete(relativeUrl string) error {
resp, err := c.sendRequest(http.MethodDelete, c.v2CrdUrl(relativeUrl), nil, nil)
if err != nil {
return err
}
defer resp.Body.Close()
if resp.StatusCode != 200 {
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return errors.Wrap(err, "error deleting")
} else {
return errors.Errorf("failed to delete: %v", string(body))
}
}
return nil
}
func (c *RESTClient) Proxy(method string, relativeUrl string, payload []byte) (*http.Response, error) {
var reader io.Reader
if len(payload) > 0 {
reader = bytes.NewReader(payload)
}
return c.sendRequest(method, c.proxyUrl(relativeUrl), nil, reader)
}
func (c *RESTClient) ServerInfo() (*http.Response, error) {
return c.sendRequest(http.MethodGet, c.url, nil, nil)
}
func (c *RESTClient) ServerURL() string {
return c.url
}
func (c *RESTClient) sendRequest(method string, relativeUrl string, headers map[string]string, reader io.Reader) (*http.Response, error) {
req, err := http.NewRequest(method, relativeUrl, reader)
if err != nil {
return nil, err
}
for k, v := range headers {
req.Header.Set(k, v)
}
// TODO: accept context
return ctxhttp.Do(context.Background(), &http.Client{}, req)
}
func (c *RESTClient) v2CrdUrl(relativeUrl string) string {
return c.url + "/v2/" + strings.TrimPrefix(relativeUrl, "/")
}
func (c *RESTClient) proxyUrl(relativeUrl string) string {
return c.url + "/proxy/" + strings.TrimPrefix(relativeUrl, "/")
}
@@ -14,30 +14,53 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"github.com/fission/fission/pkg/controller/client/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
)
func (c *Client) CanaryConfigCreate(canaryConf *fv1.CanaryConfig) (*metav1.ObjectMeta, error) {
type (
CanaryConfigGetter interface {
CanaryConfig() CanaryConfigInterface
}
CanaryConfigInterface interface {
Create(canaryConf *fv1.CanaryConfig) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.CanaryConfig, error)
Update(canaryConf *fv1.CanaryConfig) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(ns string) ([]fv1.CanaryConfig, error)
}
CanaryConfig struct {
client rest.Interface
}
)
func newCanaryConfigClient(c *V1) CanaryConfigInterface {
return &CanaryConfig{client: c.restClient}
}
func (c *CanaryConfig) Create(canaryConf *fv1.CanaryConfig) (*metav1.ObjectMeta, error) {
reqbody, err := json.Marshal(canaryConf)
if err != nil {
return nil, err
}
resp, err := c.create("canaryconfigs", "application/json", reqbody)
resp, err := c.client.Create("canaryconfigs", "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -51,17 +74,17 @@ func (c *Client) CanaryConfigCreate(canaryConf *fv1.CanaryConfig) (*metav1.Objec
return &m, nil
}
func (c *Client) CanaryConfigGet(m *metav1.ObjectMeta) (*fv1.CanaryConfig, error) {
func (c *CanaryConfig) Get(m *metav1.ObjectMeta) (*fv1.CanaryConfig, error) {
relativeUrl := fmt.Sprintf("canaryconfigs/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -75,20 +98,20 @@ func (c *Client) CanaryConfigGet(m *metav1.ObjectMeta) (*fv1.CanaryConfig, error
return &canaryCfg, nil
}
func (c *Client) CanaryConfigUpdate(canaryConf *fv1.CanaryConfig) (*metav1.ObjectMeta, error) {
func (c *CanaryConfig) Update(canaryConf *fv1.CanaryConfig) (*metav1.ObjectMeta, error) {
reqbody, err := json.Marshal(canaryConf)
if err != nil {
return nil, err
}
relativeUrl := fmt.Sprintf("canaryconfigs/%v", canaryConf.Metadata.Name)
resp, err := c.put(relativeUrl, "application/json", reqbody)
resp, err := c.client.Put(relativeUrl, "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -101,21 +124,21 @@ func (c *Client) CanaryConfigUpdate(canaryConf *fv1.CanaryConfig) (*metav1.Objec
return &m, nil
}
func (c *Client) CanaryConfigDelete(m *metav1.ObjectMeta) error {
func (c *CanaryConfig) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("canaryconfigs/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) CanaryConfigList(ns string) ([]fv1.CanaryConfig, error) {
func (c *CanaryConfig) List(ns string) ([]fv1.CanaryConfig, error) {
relativeUrl := fmt.Sprintf("canaryconfigs?namespace=%v", ns)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"github.com/fission/fission/pkg/controller/client/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -27,6 +28,24 @@ import (
v1generator "github.com/fission/fission/pkg/generator/v1"
)
type (
EnvironmentGetter interface {
Environment() EnvironmentInterface
}
EnvironmentInterface interface {
Create(env *fv1.Environment) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.Environment, error)
Update(env *fv1.Environment) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(ns string) ([]fv1.Environment, error)
}
Environment struct {
client rest.Interface
}
)
func getEnvEncodingPayload(env *fv1.Environment) ([]byte, error) {
generator, err := v1generator.CreateEnvironmentGeneratorFromObj(env)
if err != nil {
@@ -35,19 +54,23 @@ func getEnvEncodingPayload(env *fv1.Environment) ([]byte, error) {
return generator.StructuredGenerate(encoder.DefaultJSONEncoder())
}
func (c *Client) EnvironmentCreate(env *fv1.Environment) (*metav1.ObjectMeta, error) {
func newEnvironmentClient(c *V1) EnvironmentInterface {
return &Environment{client: c.restClient}
}
func (c *Environment) Create(env *fv1.Environment) (*metav1.ObjectMeta, error) {
data, err := getEnvEncodingPayload(env)
if err != nil {
return nil, err
}
resp, err := c.create("environments", "application/json", data)
resp, err := c.client.Create("environments", "application/json", data)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -61,17 +84,17 @@ func (c *Client) EnvironmentCreate(env *fv1.Environment) (*metav1.ObjectMeta, er
return &m, nil
}
func (c *Client) EnvironmentGet(m *metav1.ObjectMeta) (*fv1.Environment, error) {
func (c *Environment) Get(m *metav1.ObjectMeta) (*fv1.Environment, error) {
relativeUrl := fmt.Sprintf("environments/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -85,7 +108,7 @@ func (c *Client) EnvironmentGet(m *metav1.ObjectMeta) (*fv1.Environment, error)
return &env, nil
}
func (c *Client) EnvironmentUpdate(env *fv1.Environment) (*metav1.ObjectMeta, error) {
func (c *Environment) Update(env *fv1.Environment) (*metav1.ObjectMeta, error) {
data, err := getEnvEncodingPayload(env)
if err != nil {
return nil, err
@@ -93,13 +116,13 @@ func (c *Client) EnvironmentUpdate(env *fv1.Environment) (*metav1.ObjectMeta, er
relativeUrl := fmt.Sprintf("environments/%v", env.Metadata.Name)
resp, err := c.put(relativeUrl, "application/json", data)
resp, err := c.client.Put(relativeUrl, "application/json", data)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -112,21 +135,21 @@ func (c *Client) EnvironmentUpdate(env *fv1.Environment) (*metav1.ObjectMeta, er
return &m, nil
}
func (c *Client) EnvironmentDelete(m *metav1.ObjectMeta) error {
func (c *Environment) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("environments/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) EnvironmentList(ns string) ([]fv1.Environment, error) {
func (c *Environment) List(ns string) ([]fv1.Environment, error) {
relativeUrl := fmt.Sprintf("environments?namespace=%v", ns)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -14,23 +14,42 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"io"
"net/http"
"net/url"
"github.com/pkg/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
"github.com/fission/fission/pkg/fission-cli/console"
"github.com/fission/fission/pkg/controller/client/rest"
)
func (c *Client) FunctionCreate(f *fv1.Function) (*metav1.ObjectMeta, error) {
type (
FunctionGetter interface {
Function() FunctionInterface
}
FunctionInterface interface {
Create(f *fv1.Function) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.Function, error)
GetRawDeployment(m *metav1.ObjectMeta) ([]byte, error)
Update(f *fv1.Function) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(functionNamespace string) ([]fv1.Function, error)
}
Function struct {
client rest.Interface
}
)
func newFunctionClient(c *V1) FunctionInterface {
return &Function{client: c.restClient}
}
func (c *Function) Create(f *fv1.Function) (*metav1.ObjectMeta, error) {
err := f.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("Function", err)
@@ -41,13 +60,13 @@ func (c *Client) FunctionCreate(f *fv1.Function) (*metav1.ObjectMeta, error) {
return nil, err
}
resp, err := c.create("functions", "application/json", reqbody)
resp, err := c.client.Create("functions", "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -61,17 +80,17 @@ func (c *Client) FunctionCreate(f *fv1.Function) (*metav1.ObjectMeta, error) {
return &m, nil
}
func (c *Client) FunctionGet(m *metav1.ObjectMeta) (*fv1.Function, error) {
func (c *Function) Get(m *metav1.ObjectMeta) (*fv1.Function, error) {
relativeUrl := fmt.Sprintf("functions/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -85,21 +104,21 @@ func (c *Client) FunctionGet(m *metav1.ObjectMeta) (*fv1.Function, error) {
return &f, nil
}
func (c *Client) FunctionGetRawDeployment(m *metav1.ObjectMeta) ([]byte, error) {
func (c *Function) GetRawDeployment(m *metav1.ObjectMeta) ([]byte, error) {
relativeUrl := fmt.Sprintf("functions/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
relativeUrl += fmt.Sprintf("&deploymentraw=1")
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return c.handleResponse(resp)
return handleResponse(resp)
}
func (c *Client) FunctionUpdate(f *fv1.Function) (*metav1.ObjectMeta, error) {
func (c *Function) Update(f *fv1.Function) (*metav1.ObjectMeta, error) {
err := f.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("Function", err)
@@ -111,13 +130,13 @@ func (c *Client) FunctionUpdate(f *fv1.Function) (*metav1.ObjectMeta, error) {
}
relativeUrl := fmt.Sprintf("functions/%v", f.Metadata.Name)
resp, err := c.put(relativeUrl, "application/json", reqbody)
resp, err := c.client.Put(relativeUrl, "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -130,21 +149,21 @@ func (c *Client) FunctionUpdate(f *fv1.Function) (*metav1.ObjectMeta, error) {
return &m, nil
}
func (c *Client) FunctionDelete(m *metav1.ObjectMeta) error {
func (c *Function) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("functions/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) FunctionList(functionNamespace string) ([]fv1.Function, error) {
func (c *Function) List(functionNamespace string) ([]fv1.Function, error) {
relativeUrl := fmt.Sprintf("functions?namespace=%v", functionNamespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -157,29 +176,3 @@ func (c *Client) FunctionList(functionNamespace string) ([]fv1.Function, error)
return funcs, nil
}
func (c *Client) FunctionPodLogs(m *metav1.ObjectMeta) (io.ReadCloser, int, error) {
relativeUrl := fmt.Sprintf("functions/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
queryURL, err := url.Parse(c.Url)
if err != nil {
return nil, 0, errors.Wrapf(err, "error parsing the base URL '%v'", c.Url)
}
queryURL.Path = fmt.Sprintf("/proxy/logs/%s", m.Name)
console.Verbose(2, fmt.Sprintf("Try to get pod logs from controller '%v'", queryURL.String()))
req, err := http.NewRequest(http.MethodPost, queryURL.String(), nil)
if err != nil {
return nil, 0, errors.Wrap(err, "error creating logs request")
}
httpClient := http.Client{}
resp, err := httpClient.Do(req)
if err != nil {
return nil, 0, errors.Wrap(err, "error executing get logs request")
}
return resp.Body, resp.StatusCode, nil
}
@@ -14,18 +14,41 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"github.com/fission/fission/pkg/controller/client/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
)
func (c *Client) HTTPTriggerCreate(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, error) {
type (
HTTPTriggerGetter interface {
HTTPTrigger() HTTPTriggerInterface
}
HTTPTriggerInterface interface {
Create(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.HTTPTrigger, error)
Update(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(triggerNamespace string) ([]fv1.HTTPTrigger, error)
}
HTTPTrigger struct {
client rest.Interface
}
)
func newHTTPTriggerClient(c *V1) HTTPTriggerInterface {
return &HTTPTrigger{client: c.restClient}
}
func (c *HTTPTrigger) Create(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, error) {
err := t.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("HTTPTrigger", err)
@@ -36,13 +59,13 @@ func (c *Client) HTTPTriggerCreate(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, erro
return nil, err
}
resp, err := c.create("triggers/http", "application/json", reqbody)
resp, err := c.client.Create("triggers/http", "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -56,17 +79,17 @@ func (c *Client) HTTPTriggerCreate(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, erro
return &m, nil
}
func (c *Client) HTTPTriggerGet(m *metav1.ObjectMeta) (*fv1.HTTPTrigger, error) {
func (c *HTTPTrigger) Get(m *metav1.ObjectMeta) (*fv1.HTTPTrigger, error) {
relativeUrl := fmt.Sprintf("triggers/http/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -80,7 +103,7 @@ func (c *Client) HTTPTriggerGet(m *metav1.ObjectMeta) (*fv1.HTTPTrigger, error)
return &t, nil
}
func (c *Client) HTTPTriggerUpdate(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, error) {
func (c *HTTPTrigger) Update(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, error) {
err := t.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("HTTPTrigger", err)
@@ -92,13 +115,13 @@ func (c *Client) HTTPTriggerUpdate(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, erro
}
relativeUrl := fmt.Sprintf("triggers/http/%v", t.Metadata.Name)
resp, err := c.put(relativeUrl, "application/json", reqbody)
resp, err := c.client.Put(relativeUrl, "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -111,21 +134,21 @@ func (c *Client) HTTPTriggerUpdate(t *fv1.HTTPTrigger) (*metav1.ObjectMeta, erro
return &m, nil
}
func (c *Client) HTTPTriggerDelete(m *metav1.ObjectMeta) error {
func (c *HTTPTrigger) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("triggers/http/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) HTTPTriggerList(triggerNamespace string) ([]fv1.HTTPTrigger, error) {
func (c *HTTPTrigger) List(triggerNamespace string) ([]fv1.HTTPTrigger, error) {
relativeUrl := fmt.Sprintf("triggers/http?namespace=%v", triggerNamespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -14,11 +14,12 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"github.com/fission/fission/pkg/controller/client/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@@ -26,7 +27,29 @@ import (
ferror "github.com/fission/fission/pkg/error"
)
func (c *Client) WatchCreate(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) {
type (
KubeWatcherGetter interface {
KubeWatcher() KubeWatcherInterface
}
KubeWatcherInterface interface {
Create(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.KubernetesWatchTrigger, error)
Update(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(ns string) ([]fv1.KubernetesWatchTrigger, error)
}
KubeWatcher struct {
client rest.Interface
}
)
func newKubeWatcher(c *V1) KubeWatcherInterface {
return &KubeWatcher{client: c.restClient}
}
func (c *KubeWatcher) Create(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) {
err := w.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("KubernetesWatchTrigger", err)
@@ -37,13 +60,13 @@ func (c *Client) WatchCreate(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta,
return nil, err
}
resp, err := c.create("watches", "application/json", reqbody)
resp, err := c.client.Create("watches", "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -57,17 +80,17 @@ func (c *Client) WatchCreate(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta,
return &m, nil
}
func (c *Client) WatchGet(m *metav1.ObjectMeta) (*fv1.KubernetesWatchTrigger, error) {
func (c *KubeWatcher) Get(m *metav1.ObjectMeta) (*fv1.KubernetesWatchTrigger, error) {
relativeUrl := fmt.Sprintf("watches/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -81,25 +104,25 @@ func (c *Client) WatchGet(m *metav1.ObjectMeta) (*fv1.KubernetesWatchTrigger, er
return &w, nil
}
func (c *Client) WatchUpdate(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) {
func (c *KubeWatcher) Update(w *fv1.KubernetesWatchTrigger) (*metav1.ObjectMeta, error) {
return nil, ferror.MakeError(ferror.ErrorNotImplmented, "watch update not implemented")
}
func (c *Client) WatchDelete(m *metav1.ObjectMeta) error {
func (c *KubeWatcher) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("watches/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) WatchList(ns string) ([]fv1.KubernetesWatchTrigger, error) {
func (c *KubeWatcher) List(ns string) ([]fv1.KubernetesWatchTrigger, error) {
relativeUrl := fmt.Sprintf("watches?namespace=%v", ns)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -14,35 +14,58 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"context"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net/http"
"time"
"github.com/pkg/errors"
"golang.org/x/net/context/ctxhttp"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"github.com/fission/fission/pkg/controller/client/rest"
"github.com/fission/fission/pkg/fission-cli/console"
"github.com/fission/fission/pkg/info"
)
func (c *Client) SecretGet(m *metav1.ObjectMeta) (*apiv1.Secret, error) {
// TODO: we should remove this interface, having this for now is for backward compatibility.
type (
MiscGetter interface {
Misc() MiscInterface
}
MiscInterface interface {
SecretGet(m *metav1.ObjectMeta) (*apiv1.Secret, error)
ConfigMapGet(m *metav1.ObjectMeta) (*apiv1.ConfigMap, error)
GetSvcURL(label string) (string, error)
ServerInfo() (*info.ServerInfo, error)
PodLogs(m *metav1.ObjectMeta) (io.ReadCloser, int, error)
}
Misc struct {
client rest.Interface
}
)
func newMiscClient(c *V1) MiscInterface {
return &Misc{client: c.restClient}
}
func (c *Misc) SecretGet(m *metav1.ObjectMeta) (*apiv1.Secret, error) {
relativeUrl := fmt.Sprintf("secrets/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -56,17 +79,17 @@ func (c *Client) SecretGet(m *metav1.ObjectMeta) (*apiv1.Secret, error) {
return &secret, nil
}
func (c *Client) ConfigMapGet(m *metav1.ObjectMeta) (*apiv1.ConfigMap, error) {
func (c *Misc) ConfigMapGet(m *metav1.ObjectMeta) (*apiv1.ConfigMap, error) {
relativeUrl := fmt.Sprintf("configmaps/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -80,8 +103,8 @@ func (c *Client) ConfigMapGet(m *metav1.ObjectMeta) (*apiv1.ConfigMap, error) {
return &configMap, nil
}
func (c *Client) GetSvcURL(label string) (string, error) {
resp, err := c.proxy(http.MethodGet, "svcname?"+label, nil)
func (c *Misc) GetSvcURL(label string) (string, error) {
resp, err := c.client.Proxy(http.MethodGet, "svcname?"+label, nil)
if err != nil {
return "", err
}
@@ -100,11 +123,8 @@ func (c *Client) GetSvcURL(label string) (string, error) {
return storageSvc, err
}
func (c *Client) ServerInfo() (*info.ServerInfo, error) {
ctx, cancel := context.WithTimeout(context.Background(), 15*time.Second)
defer cancel()
resp, err := ctxhttp.Get(ctx, &http.Client{}, c.Url)
func (c *Misc) ServerInfo() (*info.ServerInfo, error) {
resp, err := c.client.ServerInfo()
if err != nil {
return nil, err
}
@@ -123,3 +143,13 @@ func (c *Client) ServerInfo() (*info.ServerInfo, error) {
return info, nil
}
func (c *Misc) PodLogs(m *metav1.ObjectMeta) (io.ReadCloser, int, error) {
uri := fmt.Sprintf("logs/%s", m.Name)
console.Verbose(2, fmt.Sprintf("Try to get pod logs from controller '%v'", uri))
resp, err := c.client.Proxy(http.MethodPost, uri, nil)
if err != nil {
return nil, 0, errors.Wrap(err, "error executing get logs request")
}
return resp.Body, resp.StatusCode, nil
}
@@ -14,18 +14,41 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"github.com/fission/fission/pkg/controller/client/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
)
func (c *Client) MessageQueueTriggerCreate(t *fv1.MessageQueueTrigger) (*metav1.ObjectMeta, error) {
type (
MessageQueueTriggerGetter interface {
MessageQueueTrigger() MessageQueueTriggerInterface
}
MessageQueueTriggerInterface interface {
Create(t *fv1.MessageQueueTrigger) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.MessageQueueTrigger, error)
Update(mqTrigger *fv1.MessageQueueTrigger) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(mqType string, ns string) ([]fv1.MessageQueueTrigger, error)
}
MessageQueueTrigger struct {
client rest.Interface
}
)
func newMessageQueueTrigger(c *V1) MessageQueueTriggerInterface {
return &MessageQueueTrigger{client: c.restClient}
}
func (c *MessageQueueTrigger) Create(t *fv1.MessageQueueTrigger) (*metav1.ObjectMeta, error) {
err := t.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("MessageQueueTrigger", err)
@@ -36,13 +59,13 @@ func (c *Client) MessageQueueTriggerCreate(t *fv1.MessageQueueTrigger) (*metav1.
return nil, err
}
resp, err := c.create("triggers/messagequeue", "application/json", reqbody)
resp, err := c.client.Create("triggers/messagequeue", "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -56,17 +79,17 @@ func (c *Client) MessageQueueTriggerCreate(t *fv1.MessageQueueTrigger) (*metav1.
return &m, nil
}
func (c *Client) MessageQueueTriggerGet(m *metav1.ObjectMeta) (*fv1.MessageQueueTrigger, error) {
func (c *MessageQueueTrigger) Get(m *metav1.ObjectMeta) (*fv1.MessageQueueTrigger, error) {
relativeUrl := fmt.Sprintf("triggers/messagequeue/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -80,7 +103,7 @@ func (c *Client) MessageQueueTriggerGet(m *metav1.ObjectMeta) (*fv1.MessageQueue
return &t, nil
}
func (c *Client) MessageQueueTriggerUpdate(mqTrigger *fv1.MessageQueueTrigger) (*metav1.ObjectMeta, error) {
func (c *MessageQueueTrigger) Update(mqTrigger *fv1.MessageQueueTrigger) (*metav1.ObjectMeta, error) {
err := mqTrigger.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("MessageQueueTrigger", err)
@@ -92,13 +115,13 @@ func (c *Client) MessageQueueTriggerUpdate(mqTrigger *fv1.MessageQueueTrigger) (
}
relativeUrl := fmt.Sprintf("triggers/messagequeue/%v", mqTrigger.Metadata.Name)
resp, err := c.put(relativeUrl, "application/json", reqbody)
resp, err := c.client.Put(relativeUrl, "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -111,26 +134,26 @@ func (c *Client) MessageQueueTriggerUpdate(mqTrigger *fv1.MessageQueueTrigger) (
return &m, nil
}
func (c *Client) MessageQueueTriggerDelete(m *metav1.ObjectMeta) error {
func (c *MessageQueueTrigger) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("triggers/messagequeue/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) MessageQueueTriggerList(mqType string, ns string) ([]fv1.MessageQueueTrigger, error) {
func (c *MessageQueueTrigger) List(mqType string, ns string) ([]fv1.MessageQueueTrigger, error) {
relativeUrl := "triggers/messagequeue"
if len(mqType) > 0 {
// TODO remove this, replace with field selector
relativeUrl += fmt.Sprintf("?mqtype=%v&namespace=%v", mqType, ns)
}
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -14,18 +14,41 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"github.com/fission/fission/pkg/controller/client/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
)
func (c *Client) PackageCreate(f *fv1.Package) (*metav1.ObjectMeta, error) {
type (
PackageGetter interface {
Package() PackageInterface
}
PackageInterface interface {
Create(f *fv1.Package) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.Package, error)
Update(f *fv1.Package) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(pkgNamespace string) ([]fv1.Package, error)
}
Package struct {
client rest.Interface
}
)
func newPackageClient(c *V1) PackageInterface {
return &Package{client: c.restClient}
}
func (c *Package) Create(f *fv1.Package) (*metav1.ObjectMeta, error) {
err := f.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("Package", err)
@@ -36,13 +59,13 @@ func (c *Client) PackageCreate(f *fv1.Package) (*metav1.ObjectMeta, error) {
return nil, err
}
resp, err := c.create("packages", "application/json", reqbody)
resp, err := c.client.Create("packages", "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -56,17 +79,17 @@ func (c *Client) PackageCreate(f *fv1.Package) (*metav1.ObjectMeta, error) {
return &m, nil
}
func (c *Client) PackageGet(m *metav1.ObjectMeta) (*fv1.Package, error) {
func (c *Package) Get(m *metav1.ObjectMeta) (*fv1.Package, error) {
relativeUrl := fmt.Sprintf("packages/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -80,7 +103,7 @@ func (c *Client) PackageGet(m *metav1.ObjectMeta) (*fv1.Package, error) {
return &f, nil
}
func (c *Client) PackageUpdate(f *fv1.Package) (*metav1.ObjectMeta, error) {
func (c *Package) Update(f *fv1.Package) (*metav1.ObjectMeta, error) {
err := f.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("Package", err)
@@ -92,13 +115,13 @@ func (c *Client) PackageUpdate(f *fv1.Package) (*metav1.ObjectMeta, error) {
}
relativeUrl := fmt.Sprintf("packages/%v", f.Metadata.Name)
resp, err := c.put(relativeUrl, "application/json", reqbody)
resp, err := c.client.Put(relativeUrl, "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -111,21 +134,21 @@ func (c *Client) PackageUpdate(f *fv1.Package) (*metav1.ObjectMeta, error) {
return &m, nil
}
func (c *Client) PackageDelete(m *metav1.ObjectMeta) error {
func (c *Package) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("packages/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) PackageList(pkgNamespace string) ([]fv1.Package, error) {
func (c *Package) List(pkgNamespace string) ([]fv1.Package, error) {
relativeUrl := fmt.Sprintf("packages?namespace=%v", pkgNamespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -14,18 +14,41 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
package client
package v1
import (
"encoding/json"
"fmt"
"github.com/fission/fission/pkg/controller/client/rest"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
fv1 "github.com/fission/fission/pkg/apis/fission.io/v1"
)
func (c *Client) TimeTriggerCreate(t *fv1.TimeTrigger) (*metav1.ObjectMeta, error) {
type (
TimeTriggerGetter interface {
TimeTrigger() TimeTriggerInterface
}
TimeTriggerInterface interface {
Create(t *fv1.TimeTrigger) (*metav1.ObjectMeta, error)
Get(m *metav1.ObjectMeta) (*fv1.TimeTrigger, error)
Update(t *fv1.TimeTrigger) (*metav1.ObjectMeta, error)
Delete(m *metav1.ObjectMeta) error
List(ns string) ([]fv1.TimeTrigger, error)
}
TimeTrigger struct {
client rest.Interface
}
)
func newTimeTriggerClient(c *V1) TimeTriggerInterface {
return &TimeTrigger{client: c.restClient}
}
func (c *TimeTrigger) Create(t *fv1.TimeTrigger) (*metav1.ObjectMeta, error) {
err := t.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("TimeTrigger", err)
@@ -36,13 +59,13 @@ func (c *Client) TimeTriggerCreate(t *fv1.TimeTrigger) (*metav1.ObjectMeta, erro
return nil, err
}
resp, err := c.create("triggers/time", "application/json", reqbody)
resp, err := c.client.Create("triggers/time", "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleCreateResponse(resp)
body, err := handleCreateResponse(resp)
if err != nil {
return nil, err
}
@@ -56,17 +79,17 @@ func (c *Client) TimeTriggerCreate(t *fv1.TimeTrigger) (*metav1.ObjectMeta, erro
return &m, nil
}
func (c *Client) TimeTriggerGet(m *metav1.ObjectMeta) (*fv1.TimeTrigger, error) {
func (c *TimeTrigger) Get(m *metav1.ObjectMeta) (*fv1.TimeTrigger, error) {
relativeUrl := fmt.Sprintf("triggers/time/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -80,7 +103,7 @@ func (c *Client) TimeTriggerGet(m *metav1.ObjectMeta) (*fv1.TimeTrigger, error)
return &t, nil
}
func (c *Client) TimeTriggerUpdate(t *fv1.TimeTrigger) (*metav1.ObjectMeta, error) {
func (c *TimeTrigger) Update(t *fv1.TimeTrigger) (*metav1.ObjectMeta, error) {
err := t.Validate()
if err != nil {
return nil, fv1.AggregateValidationErrors("TimeTrigger", err)
@@ -92,13 +115,13 @@ func (c *Client) TimeTriggerUpdate(t *fv1.TimeTrigger) (*metav1.ObjectMeta, erro
}
relativeUrl := fmt.Sprintf("triggers/time/%v", t.Metadata.Name)
resp, err := c.put(relativeUrl, "application/json", reqbody)
resp, err := c.client.Put(relativeUrl, "application/json", reqbody)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
@@ -111,21 +134,21 @@ func (c *Client) TimeTriggerUpdate(t *fv1.TimeTrigger) (*metav1.ObjectMeta, erro
return &m, nil
}
func (c *Client) TimeTriggerDelete(m *metav1.ObjectMeta) error {
func (c *TimeTrigger) Delete(m *metav1.ObjectMeta) error {
relativeUrl := fmt.Sprintf("triggers/time/%v", m.Name)
relativeUrl += fmt.Sprintf("?namespace=%v", m.Namespace)
return c.delete(relativeUrl)
return c.client.Delete(relativeUrl)
}
func (c *Client) TimeTriggerList(ns string) ([]fv1.TimeTrigger, error) {
func (c *TimeTrigger) List(ns string) ([]fv1.TimeTrigger, error) {
relativeUrl := fmt.Sprintf("triggers/time?namespace=%v", ns)
resp, err := c.get(relativeUrl)
resp, err := c.client.Get(relativeUrl)
if err != nil {
return nil, err
}
defer resp.Body.Close()
body, err := c.handleResponse(resp)
body, err := handleResponse(resp)
if err != nil {
return nil, err
}
+100
View File
@@ -0,0 +1,100 @@
/*
Copyright 2019 The Fission Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package v1
import (
"io/ioutil"
"net/http"
ferror "github.com/fission/fission/pkg/error"
"github.com/fission/fission/pkg/controller/client/rest"
)
type (
V1Interface interface {
MiscGetter
CanaryConfigGetter
EnvironmentGetter
FunctionGetter
HTTPTriggerGetter
KubeWatcherGetter
MessageQueueTriggerGetter
PackageGetter
TimeTriggerGetter
}
V1 struct {
restClient rest.Interface
}
)
func MakeV1Client(restClient rest.Interface) *V1 {
return &V1{restClient: restClient}
}
func (c *V1) Misc() MiscInterface {
return newMiscClient(c)
}
func (c *V1) CanaryConfig() CanaryConfigInterface {
return newCanaryConfigClient(c)
}
func (c *V1) Environment() EnvironmentInterface {
return newEnvironmentClient(c)
}
func (c *V1) Function() FunctionInterface {
return newFunctionClient(c)
}
func (c *V1) HTTPTrigger() HTTPTriggerInterface {
return newHTTPTriggerClient(c)
}
func (c *V1) KubeWatcher() KubeWatcherInterface {
return newKubeWatcher(c)
}
func (c *V1) MessageQueueTrigger() MessageQueueTriggerInterface {
return newMessageQueueTrigger(c)
}
func (c *V1) Package() PackageInterface {
return newPackageClient(c)
}
func (c *V1) TimeTrigger() TimeTriggerInterface {
return newTimeTriggerClient(c)
}
func handleResponse(resp *http.Response) ([]byte, error) {
if resp.StatusCode != 200 {
return nil, ferror.MakeErrorFromHTTP(resp)
}
body, err := ioutil.ReadAll(resp.Body)
return body, err
}
func handleCreateResponse(resp *http.Response) ([]byte, error) {
if resp.StatusCode != 201 {
return nil, ferror.MakeErrorFromHTTP(resp)
}
body, err := ioutil.ReadAll(resp.Body)
return body, err
}