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

VX-72 VX-73 VX-74 Add pod get function & regex name check & api docs #84

Merged
merged 2 commits into from
Jul 11, 2018
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 117 additions & 2 deletions API.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ accessMode: The accessMode of the Volume including the following options.
- ReadWriteMany
- ReeaOneMany
But those options won't work for NFS storage since the permission is controled by the linux permission system.
capacity: The capacity of the volume,
capacity: The capacity of the volume,

Example:

Expand Down Expand Up @@ -270,7 +270,7 @@ Response Data:
"storageName": "My First Storage2",
"accessMode": "ReadWriteMany",
"capacity": "300",
"createdAt": "2018-07-09T05:27:56.244Z"
"createdAt": "2018-07-09T05:27:56.244Z"
}
]
```
Expand All @@ -294,3 +294,118 @@ Response Data:
"message": "Delete success"
}
```

## Pod

### Create Pod

**POST /v1/pods**

Example:

```
curl -X POST -H "Content-Type: application/json" \
-d '{"name":"awesome","containers":[{"name":"busybox","image":"busybox","command":["sleep","3600"]}]}' \
http://localhost:7890/v1/pods
```

Request Data:

```json
{
"name": "awesome",
"containers": [{
"name": "busybox",
"image": "busybox",
"command": ["sleep", "3600"]
}]
}
```

Response Data:

```json
{
"error": false,
"message": "Create success"
}
```

### List Pods

**GET /v1/pods/**

Example:

```
curl http://localhost:7890/v1/pods/
```

Response Data:

```json
[{
"id": "5b459d344807c5707ddad740",
"name": "awesome",
"containers": [
{
"name": "busybox",
"image": "busybox",
"command": [
"sleep",
"3600"
]
}
],
"createdAt": "2018-07-11T06:01:24.637Z"
}]
```

### Get Pod

**GET /v1/pods/[id]**

Example:

```
curl http://localhost:7890/v1/pods/5b459d344807c5707ddad740
```

Response Data:

```json
{
"id": "5b459d344807c5707ddad740",
"name": "awesome",
"containers": [
{
"name": "busybox",
"image": "busybox",
"command": [
"sleep",
"3600"
]
}
],
"createdAt": "2018-07-11T06:01:24.637Z"
}
```

### Delete Pod

**DELETE /v1/pods/[id]**

Example:

```
curl -X DELETE http://localhost:7890/v1/pods/5b459d344807c5707ddad740
```

Response Data:

```json
{
"error": false,
"message": "Delete success"
}
```
20 changes: 20 additions & 0 deletions src/pod/pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package pod

import (
"fmt"
"regexp"

"github.com/linkernetworks/mongo"
"github.com/linkernetworks/vortex/src/entity"
Expand All @@ -15,9 +16,27 @@ import (

const VolumeNamePrefix = "volume-"

func checkNameValidation(name string) bool {
re := regexp.MustCompile(`[a-z0-9]([-a-z0-9]*[a-z0-9])`)
return re.MatchString(name)
}

func CheckPodParameter(sp *serviceprovider.Container, pod *entity.Pod) error {
session := sp.Mongo.NewSession()
defer session.Close()

//Check pod name validation
if !checkNameValidation(pod.Name) {
return fmt.Errorf("Pod Name: %s is invalid value", pod.Name)
}

//Check container name validation
for _, container := range pod.Containers {
if !checkNameValidation(container.Name) {
return fmt.Errorf("Container Name: %s is invalid value", container.Name)
}
}

//Check the volume
for _, v := range pod.Volumes {
count, err := session.Count(entity.VolumeCollectionName, bson.M{"name": v.Name})
Expand Down Expand Up @@ -79,6 +98,7 @@ func CreatePod(sp *serviceprovider.Container, pod *entity.Pod) error {
VolumeMounts: volumeMounts,
})
}

p := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: pod.Name,
Expand Down
22 changes: 21 additions & 1 deletion src/pod/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ func TestPodSuite(t *testing.T) {
func (suite *PodTestSuite) TestCheckPodParameter() {
volumeName := namesgenerator.GetRandomName(0)
pod := &entity.Pod{
ID: bson.NewObjectId(),
ID: bson.NewObjectId(),
Name: namesgenerator.GetRandomName(0),
Volumes: []entity.PodVolume{
{Name: volumeName},
},
Expand All @@ -62,6 +63,25 @@ func (suite *PodTestSuite) TestCheckPodParameterFail() {
caseName string
pod *entity.Pod
}{
{
"InvalidPodName", &entity.Pod{
ID: bson.NewObjectId(),
Name: "~!@#$%^&*()",
},
},
{
"InvalidContainerName", &entity.Pod{
ID: bson.NewObjectId(),
Name: namesgenerator.GetRandomName(0),
Containers: []entity.Container{
{
Name: "~!@#$%^&*()",
Image: "busybox",
Command: []string{"sleep", "3600"},
},
},
},
},
{
"InvalidVolume", &entity.Pod{
ID: bson.NewObjectId(),
Expand Down
2 changes: 1 addition & 1 deletion src/server/handler_network_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ func (suite *NetworkTestSuite) TestDeleteNetworkFail() {
}
}

//Fot Get/List, we only return mongo document
//For Get/List, we only return mongo document
func (suite *NetworkTestSuite) TestGetNetwork() {
tName := namesgenerator.GetRandomName(0)
tType := entity.FakeNetworkType
Expand Down
27 changes: 24 additions & 3 deletions src/server/handler_pod.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
"gopkg.in/mgo.v2/bson"
)

func createPod(ctx *web.Context) {
func createPodHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

p := entity.Pod{}
Expand Down Expand Up @@ -59,7 +59,7 @@ func createPod(ctx *web.Context) {
})
}

func deletePod(ctx *web.Context) {
func deletePodHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

id := req.PathParameter("id")
Expand Down Expand Up @@ -93,7 +93,7 @@ func deletePod(ctx *web.Context) {
})
}

func listPod(ctx *web.Context) {
func listPodHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

var pageSize = 10
Expand Down Expand Up @@ -139,3 +139,24 @@ func listPod(ctx *web.Context) {
resp.AddHeader("X-Total-Pages", strconv.Itoa(totalPages))
resp.WriteEntity(pods)
}

func getPodHandler(ctx *web.Context) {
sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response

id := req.PathParameter("id")

session := sp.Mongo.NewSession()
defer session.Close()
c := session.C(entity.PodCollectionName)

var pod entity.Pod
if err := c.FindId(bson.ObjectIdHex(id)).One(&pod); err != nil {
if err == mgo.ErrNotFound {
response.NotFound(req.Request, resp.ResponseWriter, err)
} else {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
}
return
}
resp.WriteEntity(pod)
}
45 changes: 45 additions & 0 deletions src/server/handler_pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,51 @@ func (suite *PodTestSuite) TestDeletePodWithInvalidID() {
assertResponseCode(suite.T(), http.StatusBadRequest, httpWriter)
}

//For Get/List, we only return mongo document
func (suite *PodTestSuite) TestGetPod() {
containers := []entity.Container{
{
Name: namesgenerator.GetRandomName(0),
Image: "busybox",
Command: []string{"sleep", "3600"},
},
}
tName := namesgenerator.GetRandomName(0)
pod := entity.Pod{
ID: bson.NewObjectId(),
Name: tName,
Containers: containers,
}

//Create data into mongo manually
suite.session.C(entity.PodCollectionName).Insert(pod)
defer suite.session.Remove(entity.PodCollectionName, "name", tName)

httpRequest, err := http.NewRequest("GET", "http://localhost:7890/v1/pods/"+pod.ID.Hex(), nil)
suite.NoError(err)

httpWriter := httptest.NewRecorder()
suite.wc.Dispatch(httpWriter, httpRequest)
assertResponseCode(suite.T(), http.StatusOK, httpWriter)

pod = entity.Pod{}
err = json.Unmarshal(httpWriter.Body.Bytes(), &pod)
suite.NoError(err)
suite.Equal(tName, pod.Name)
suite.Equal(len(containers), len(pod.Containers))
}

func (suite *PodTestSuite) TestGetPodWithInvalidID() {

//Get data with non-exits ID
httpRequest, err := http.NewRequest("GET", "http://localhost:7890/v1/pods/"+bson.NewObjectId().Hex(), nil)
suite.NoError(err)

httpWriter := httptest.NewRecorder()
suite.wc.Dispatch(httpWriter, httpRequest)
assertResponseCode(suite.T(), http.StatusNotFound, httpWriter)
}

func (suite *PodTestSuite) TestListPod() {
pods := []entity.Pod{}
count := 3
Expand Down
7 changes: 4 additions & 3 deletions src/server/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,9 +63,10 @@ func newVolumeService(sp *serviceprovider.Container) *restful.WebService {
func newPodService(sp *serviceprovider.Container) *restful.WebService {
webService := new(restful.WebService)
webService.Path("/v1/pods").Consumes(restful.MIME_JSON, restful.MIME_JSON).Produces(restful.MIME_JSON, restful.MIME_JSON)
webService.Route(webService.POST("/").To(handler.RESTfulServiceHandler(sp, createPod)))
webService.Route(webService.DELETE("/{id}").To(handler.RESTfulServiceHandler(sp, deletePod)))
webService.Route(webService.GET("/").To(handler.RESTfulServiceHandler(sp, listPod)))
webService.Route(webService.POST("/").To(handler.RESTfulServiceHandler(sp, createPodHandler)))
webService.Route(webService.DELETE("/{id}").To(handler.RESTfulServiceHandler(sp, deletePodHandler)))
webService.Route(webService.GET("/").To(handler.RESTfulServiceHandler(sp, listPodHandler)))
webService.Route(webService.GET("/{id}").To(handler.RESTfulServiceHandler(sp, getPodHandler)))
return webService
}

Expand Down