Merge pull request #8 from platform9/controller-environment-api
API for environments
This commit is contained in:
+5
-5
@@ -90,11 +90,11 @@ func (api *API) serve(port int) {
|
||||
r.HandleFunc("/triggers/http/{httpTrigger}", api.HTTPTriggerApiUpdate).Methods("PUT")
|
||||
r.HandleFunc("/triggers/http/{httpTrigger}", api.HTTPTriggerApiDelete).Methods("DELETE")
|
||||
|
||||
// r.HandleFunc("/environments", api.EnvironmentApiList).Methods("GET")
|
||||
// r.HandleFunc("/environments", api.EnvironmentApiCreate).Methods("POST")
|
||||
// r.HandleFunc("/environments/{environment}", api.EnvironmentApiGet).Methods("GET")
|
||||
// r.HandleFunc("/environments/{environment}", api.EnvironmentApiUpdate).Methods("PUT")
|
||||
// r.HandleFunc("/environments/{environment}", api.EnvironmentApiDelete).Methods("DELETE")
|
||||
r.HandleFunc("/environments", api.EnvironmentApiList).Methods("GET")
|
||||
r.HandleFunc("/environments", api.EnvironmentApiCreate).Methods("POST")
|
||||
r.HandleFunc("/environments/{environment}", api.EnvironmentApiGet).Methods("GET")
|
||||
r.HandleFunc("/environments/{environment}", api.EnvironmentApiUpdate).Methods("PUT")
|
||||
r.HandleFunc("/environments/{environment}", api.EnvironmentApiDelete).Methods("DELETE")
|
||||
|
||||
address := fmt.Sprintf(":%v", port)
|
||||
|
||||
|
||||
@@ -152,6 +152,51 @@ func TestHTTPTriggerApi(t *testing.T) {
|
||||
assert(len(ts) == 2, "created two triggers, but didn't find them")
|
||||
}
|
||||
|
||||
func TestEnvironmentApi(t *testing.T) {
|
||||
testEnv := &fission.Environment{
|
||||
Metadata: fission.Metadata{
|
||||
Name: "xxx",
|
||||
Uid: "yyy",
|
||||
},
|
||||
RunContainerImageUrl: "gcr.io/xyz",
|
||||
}
|
||||
uid, err := g.client.EnvironmentCreate(testEnv)
|
||||
panicIf(err)
|
||||
m := &fission.Metadata{
|
||||
Name: testEnv.Metadata.Name,
|
||||
Uid: uid,
|
||||
}
|
||||
defer g.client.EnvironmentDelete(m)
|
||||
|
||||
tr, err := g.client.EnvironmentGet(m)
|
||||
panicIf(err)
|
||||
testEnv.Metadata.Uid = m.Uid
|
||||
assert(*testEnv == *tr, "env should match after reading")
|
||||
|
||||
testEnv.RunContainerImageUrl = "/hi"
|
||||
uid2, err := g.client.EnvironmentUpdate(testEnv)
|
||||
panicIf(err)
|
||||
|
||||
m.Uid = uid2
|
||||
tr, err = g.client.EnvironmentGet(m)
|
||||
panicIf(err)
|
||||
testEnv.Metadata.Uid = m.Uid
|
||||
assert(*testEnv == *tr, "env should match after reading")
|
||||
|
||||
testEnv.Metadata.Name = "yyy"
|
||||
uid, err = g.client.EnvironmentCreate(testEnv)
|
||||
panicIf(err)
|
||||
m = &fission.Metadata{
|
||||
Name: testEnv.Metadata.Name,
|
||||
Uid: uid,
|
||||
}
|
||||
defer g.client.EnvironmentDelete(m)
|
||||
|
||||
ts, err := g.client.EnvironmentList()
|
||||
panicIf(err)
|
||||
assert(len(ts) == 2, "created two envs, but didn't find them")
|
||||
}
|
||||
|
||||
func TestMain(m *testing.M) {
|
||||
flag.Parse()
|
||||
|
||||
@@ -167,6 +212,7 @@ func TestMain(m *testing.M) {
|
||||
|
||||
ks.Delete(context.Background(), "Function", &etcdClient.DeleteOptions{Recursive: true})
|
||||
ks.Delete(context.Background(), "HTTPTrigger", &etcdClient.DeleteOptions{Recursive: true})
|
||||
ks.Delete(context.Background(), "Environment", &etcdClient.DeleteOptions{Recursive: true})
|
||||
|
||||
go api.serve(8888)
|
||||
time.Sleep(500 * time.Millisecond)
|
||||
|
||||
+110
-10
@@ -318,13 +318,113 @@ func (c *Client) HTTPTriggerList() ([]fission.HTTPTrigger, error) {
|
||||
return triggers, nil
|
||||
}
|
||||
|
||||
// func (c *Client) EnvironmentCreate(f *fission.Environment) (string, error) {
|
||||
// }
|
||||
// func (c *Client) EnvironmentGet(m *fission.Metadata) (*fission.Environment, error) {
|
||||
// }
|
||||
// func (c *Client) EnvironmentUpdate(f *fission.Environment) (string, error) {
|
||||
// }
|
||||
// func (c *Client) EnvironmentDelete(m *fission.Metadata) error {
|
||||
// }
|
||||
// func (c *Client) EnvironmentList() ([]fission.Environment, error) {
|
||||
// }
|
||||
func (c *Client) EnvironmentCreate(env *fission.Environment) (string, error) {
|
||||
reqbody, err := json.Marshal(env)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
resp, err := http.Post(c.url("environments"), "application/json", bytes.NewReader(reqbody))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := c.handleResponse(resp)
|
||||
if err != nil {
|
||||
log.WithFields(log.Fields{
|
||||
"name": env.Metadata.Name,
|
||||
"err": err,
|
||||
}).Error("Failed to create environment")
|
||||
return "", err
|
||||
}
|
||||
|
||||
var m fission.Metadata
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return m.Uid, nil
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentGet(m *fission.Metadata) (*fission.Environment, error) {
|
||||
relativeUrl := fmt.Sprintf("environments/%v", m.Name)
|
||||
if len(m.Uid) > 0 {
|
||||
relativeUrl += fmt.Sprintf("?uid=%v", m.Uid)
|
||||
}
|
||||
|
||||
resp, err := http.Get(c.url(relativeUrl))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := c.handleResponse(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var env fission.Environment
|
||||
err = json.Unmarshal(body, &env)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &env, nil
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentUpdate(env *fission.Environment) (string, error) {
|
||||
reqbody, err := json.Marshal(env)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
relativeUrl := fmt.Sprintf("environments/%v", env.Metadata.Name)
|
||||
|
||||
resp, err := c.put(relativeUrl, "application/json", reqbody)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
body, err := c.handleResponse(resp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var m fission.Metadata
|
||||
err = json.Unmarshal(body, &m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return m.Uid, nil
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentDelete(m *fission.Metadata) error {
|
||||
relativeUrl := fmt.Sprintf("environments/%v", m.Name)
|
||||
if len(m.Uid) > 0 {
|
||||
relativeUrl += fmt.Sprintf("?uid=%v", m.Uid)
|
||||
}
|
||||
err := c.delete(relativeUrl)
|
||||
return err
|
||||
}
|
||||
|
||||
func (c *Client) EnvironmentList() ([]fission.Environment, error) {
|
||||
resp, err := http.Get(c.url("environments"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
body, err := c.handleResponse(resp)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
envs := make([]fission.Environment, 0)
|
||||
err = json.Unmarshal(body, &envs)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
Copyright 2016 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 controller
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
|
||||
log "github.com/Sirupsen/logrus"
|
||||
"github.com/gorilla/mux"
|
||||
|
||||
"github.com/platform9/fission"
|
||||
)
|
||||
|
||||
func (api *API) EnvironmentApiList(w http.ResponseWriter, r *http.Request) {
|
||||
envs, err := api.EnvironmentStore.List()
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := json.Marshal(envs)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.respondWithSuccess(w, resp)
|
||||
}
|
||||
|
||||
func (api *API) EnvironmentApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
}
|
||||
|
||||
var env fission.Environment
|
||||
err = json.Unmarshal(body, &env)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
uid, err := api.EnvironmentStore.Create(&env)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
m := &fission.Metadata{Name: env.Metadata.Name, Uid: uid}
|
||||
resp, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.respondWithSuccess(w, resp)
|
||||
}
|
||||
|
||||
func (api *API) EnvironmentApiGet(w http.ResponseWriter, r *http.Request) {
|
||||
var m fission.Metadata
|
||||
|
||||
vars := mux.Vars(r)
|
||||
m.Name = vars["environment"]
|
||||
m.Uid = r.FormValue("uid") // empty if uid is absent
|
||||
|
||||
env, err := api.EnvironmentStore.Get(&m)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
resp, err := json.Marshal(env)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.respondWithSuccess(w, resp)
|
||||
}
|
||||
|
||||
func (api *API) EnvironmentApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
name := vars["environment"]
|
||||
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
}
|
||||
|
||||
var env fission.Environment
|
||||
err = json.Unmarshal(body, &env)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
if name != env.Metadata.Name {
|
||||
err = fission.MakeError(fission.ErrorInvalidArgument, "Environment name doesn't match URL")
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
uid, err := api.EnvironmentStore.Update(&env)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
m := &fission.Metadata{Name: env.Metadata.Name, Uid: uid}
|
||||
resp, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
api.respondWithSuccess(w, resp)
|
||||
}
|
||||
|
||||
func (api *API) EnvironmentApiDelete(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
var m fission.Metadata
|
||||
m.Name = vars["environment"]
|
||||
|
||||
m.Uid = r.FormValue("uid") // empty if uid is absent
|
||||
if len(m.Uid) == 0 {
|
||||
log.WithFields(log.Fields{"httpTrigger": m.Name}).Info("Deleting all versions")
|
||||
}
|
||||
|
||||
err := api.EnvironmentStore.Delete(m)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
return
|
||||
}
|
||||
|
||||
api.respondWithSuccess(w, []byte(""))
|
||||
}
|
||||
@@ -26,12 +26,12 @@ type EnvironmentStore struct {
|
||||
resourceStore
|
||||
}
|
||||
|
||||
func (es *EnvironmentStore) create(e *fission.Environment) error {
|
||||
func (es *EnvironmentStore) Create(e *fission.Environment) (string, error) {
|
||||
e.Metadata.Uid = uuid.NewV4().String()
|
||||
return es.resourceStore.create(e)
|
||||
return e.Metadata.Uid, es.resourceStore.create(e)
|
||||
}
|
||||
|
||||
func (es *EnvironmentStore) read(m fission.Metadata) (*fission.Environment, error) {
|
||||
func (es *EnvironmentStore) Get(m *fission.Metadata) (*fission.Environment, error) {
|
||||
var e fission.Environment
|
||||
err := es.resourceStore.read(m.Name, &e)
|
||||
if err != nil {
|
||||
@@ -40,12 +40,12 @@ func (es *EnvironmentStore) read(m fission.Metadata) (*fission.Environment, erro
|
||||
return &e, nil
|
||||
}
|
||||
|
||||
func (es *EnvironmentStore) update(e *fission.Environment) error {
|
||||
func (es *EnvironmentStore) Update(e *fission.Environment) (string, error) {
|
||||
e.Metadata.Uid = uuid.NewV4().String()
|
||||
return es.resourceStore.update(e)
|
||||
return e.Metadata.Uid, es.resourceStore.update(e)
|
||||
}
|
||||
|
||||
func (es *EnvironmentStore) delete(m fission.Metadata) error {
|
||||
func (es *EnvironmentStore) Delete(m fission.Metadata) error {
|
||||
typeName, err := getTypeName(fission.Environment{})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -53,7 +53,7 @@ func (es *EnvironmentStore) delete(m fission.Metadata) error {
|
||||
return es.resourceStore.delete(typeName, m.Name)
|
||||
}
|
||||
|
||||
func (es *EnvironmentStore) list() ([]fission.Environment, error) {
|
||||
func (es *EnvironmentStore) List() ([]fission.Environment, error) {
|
||||
typeName, err := getTypeName(fission.Environment{})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -64,7 +64,7 @@ func (es *EnvironmentStore) list() ([]fission.Environment, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
triggers := make([]fission.Environment, 0, len(bufs))
|
||||
envs := make([]fission.Environment, 0, len(bufs))
|
||||
js := JsonSerializer{}
|
||||
for _, buf := range bufs {
|
||||
var e fission.Environment
|
||||
@@ -72,8 +72,8 @@ func (es *EnvironmentStore) list() ([]fission.Environment, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
triggers = append(triggers, e)
|
||||
envs = append(envs, e)
|
||||
}
|
||||
|
||||
return triggers, nil
|
||||
return envs, nil
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func (api *API) HTTPTriggerApiCreate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
m := &fission.Metadata{Name: t.Name, Uid: uid}
|
||||
m := &fission.Metadata{Name: t.Metadata.Name, Uid: uid}
|
||||
resp, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
@@ -122,7 +122,7 @@ func (api *API) HTTPTriggerApiUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
m := &fission.Metadata{Name: t.Name, Uid: uid}
|
||||
m := &fission.Metadata{Name: t.Metadata.Name, Uid: uid}
|
||||
resp, err := json.Marshal(m)
|
||||
if err != nil {
|
||||
api.respondWithError(w, err)
|
||||
|
||||
Reference in New Issue
Block a user