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 1 commit
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"
}
```
13 changes: 13 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 Down Expand Up @@ -60,6 +61,11 @@ func generateVolume(pod *entity.Pod, session *mongo.Session) ([]corev1.Volume, [
return volumes, volumeMounts, nil
}

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

func CreatePod(sp *serviceprovider.Container, pod *entity.Pod) error {

session := sp.Mongo.NewSession()
Expand All @@ -72,13 +78,20 @@ func CreatePod(sp *serviceprovider.Container, pod *entity.Pod) error {

var containers []corev1.Container
for _, container := range pod.Containers {
if !checkName(container.Name) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can check the name in the CheckPodParameter function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

update

return fmt.Errorf("Container Name: %s is invalid value", container.Name)
}
containers = append(containers, corev1.Container{
Name: container.Name,
Image: container.Image,
Command: container.Command,
VolumeMounts: volumeMounts,
})
}

if !checkName(pod.Name) {
return fmt.Errorf("Pod Name: %s is invalid value", pod.Name)
}
p := corev1.Pod{
ObjectMeta: metav1.ObjectMeta{
Name: pod.Name,
Expand Down
32 changes: 29 additions & 3 deletions src/pod/pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,42 @@ func (suite *PodTestSuite) TestCreatePod() {
}

func (suite *PodTestSuite) TestCreatePodFail() {
podName := "~!@#$%^&*()"
pod := &entity.Pod{
ID: bson.NewObjectId(),
Name: podName,
}

err := CreatePod(suite.sp, pod)
suite.Error(err)

containers := []entity.Container{
{
Name: "~!@#$%^&*()",
Image: "busybox",
Command: []string{"sleep", "3600"},
},
}
podName = namesgenerator.GetRandomName(0)
pod = &entity.Pod{
ID: bson.NewObjectId(),
Name: podName,
Containers: containers,
}

err = CreatePod(suite.sp, pod)
suite.Error(err)

containers = []entity.Container{
{
Name: namesgenerator.GetRandomName(0),
Image: "busybox",
Command: []string{"sleep", "3600"},
},
}

podName := namesgenerator.GetRandomName(0)
pod := &entity.Pod{
podName = namesgenerator.GetRandomName(0)
pod = &entity.Pod{
ID: bson.NewObjectId(),
Name: podName,
Containers: containers,
Expand All @@ -165,6 +191,6 @@ func (suite *PodTestSuite) TestCreatePodFail() {
},
}

err := CreatePod(suite.sp, pod)
err = CreatePod(suite.sp, pod)
suite.Error(err)
}
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
29 changes: 25 additions & 4 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 All @@ -41,7 +41,7 @@ func createPod(ctx *web.Context) {
}

if err := pod.CreatePod(sp, &p); err != nil {
response.InternalServerError(req.Request, resp.ResponseWriter, err)
response.BadRequest(req.Request, resp.ResponseWriter, err)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keep the InternalServerError, we will check the parameter in the above function pod.CheckPodParameter

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix

return
}
if err := session.Insert(entity.PodCollectionName, &p); err != nil {
Expand All @@ -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)
}
47 changes: 46 additions & 1 deletion src/server/handler_pod_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ func (suite *PodTestSuite) TestCreatePod() {
httpRequest.Header.Add("Content-Type", "application/json")
httpWriter = httptest.NewRecorder()
suite.wc.Dispatch(httpWriter, httpRequest)
assertResponseCode(suite.T(), http.StatusInternalServerError, httpWriter)
assertResponseCode(suite.T(), http.StatusBadRequest, httpWriter)

err = p.DeletePod(suite.sp, tName)
suite.NoError(err)
Expand Down 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