diff --git a/API.md b/API.md index e8af673c..e18fb3e9 100644 --- a/API.md +++ b/API.md @@ -18,6 +18,7 @@ - [Get Network](#get-network) - [Get Network Status](#get-network-status) - [Delete Network](#delete-network) + - [Get Open vSwitch Shell Infomation](#get-open-vswitch-shell-information) - [Storage](#storage) - [Create Storage](#create-storage) - [List Storage](#list-storage) @@ -480,6 +481,26 @@ Response Data: } ``` +### Get Open vSwitch Shell Information + +**DELETE /v1/networks/[nodeName]/shell** + +Example: + +``` +curl -X GET http://localhost:7890/v1/networks/node-1/shell +``` + +Response Data: + +```json +{ + "namespace": "vortex", + "podName": "openvswitch-exec-df12a", + "containerName": "openvswitch-exec" +} +``` + ## Storage ### Create Storage diff --git a/config/k8s.json b/config/k8s.json index cd354fe9..4d4bd4c0 100644 --- a/config/k8s.json +++ b/config/k8s.json @@ -11,6 +11,9 @@ "registry": { "url": "https://dockerhub.pw" }, + "kubernetes": { + "systemNamespace": "vortex" + }, "logger": { "dir": "./logs", "level": "debug", diff --git a/config/local.json b/config/local.json index 4cf52c62..ed85f62a 100644 --- a/config/local.json +++ b/config/local.json @@ -8,6 +8,9 @@ "registry": { "url": "https://dockerhub.pw" }, + "kubernetes": { + "systemNamespace": "vortex" + }, "logger": { "dir": "./logs", "level": "debug", diff --git a/config/testing.json b/config/testing.json index 555302cc..89a8a80d 100644 --- a/config/testing.json +++ b/config/testing.json @@ -8,6 +8,9 @@ "registry": { "url": "https://dockerhub.pw" }, + "kubernetes": { + "systemNamespace": "vortex" + }, "logger": { "dir": "./logs", "level": "debug", diff --git a/src/config/config.go b/src/config/config.go index e9ea21b1..29a70561 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -16,6 +16,7 @@ type Config struct { Mongo *mongo.MongoConfig `json:"mongo"` Prometheus *prometheusprovider.PrometheusConfig `json:"prometheus"` Registry *registry.Config `json:"registry"` + Kubernetes *kubernetesConfig `json:"kubernetes"` Logger logger.LoggerConfig `json:"logger"` // the version settings of the current application diff --git a/src/config/kubernetes.go b/src/config/kubernetes.go new file mode 100644 index 00000000..24e1bd77 --- /dev/null +++ b/src/config/kubernetes.go @@ -0,0 +1,5 @@ +package config + +type kubernetesConfig struct { + SystemNamespace string `json:"systemNamespace"` +} diff --git a/src/server/handler_network.go b/src/server/handler_network.go index f8114647..d17f070e 100644 --- a/src/server/handler_network.go +++ b/src/server/handler_network.go @@ -5,6 +5,7 @@ import ( "math" "net/http" "strconv" + "strings" "github.com/linkernetworks/utils/timeutils" "github.com/linkernetworks/vortex/src/entity" @@ -19,6 +20,12 @@ import ( "gopkg.in/mgo.v2/bson" ) +type shellOVSInfoResponse struct { + Namespace string `json:"namespace"` + PodName string `json:"podName"` + ContainerName string `json:"containerName"` +} + func createNetworkHandler(ctx *web.Context) { sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response userID, ok := req.Attribute("UserID").(string) @@ -247,3 +254,42 @@ func deleteNetworkHandler(ctx *web.Context) { Message: "Delete success", }) } + +func getOVSShellInfoHandler(ctx *web.Context) { + sp, req, resp := ctx.ServiceProvider, ctx.Request, ctx.Response + nodeName := req.PathParameter("node") + + pods, err := sp.KubeCtl.GetPods(sp.Config.Kubernetes.SystemNamespace) + if err != nil { + response.InternalServerError(req.Request, resp.ResponseWriter, err) + return + } + + var podName, containerName string + if len(pods) == 0 { + resp.WriteHeaderAndEntity(http.StatusNotFound, shellOVSInfoResponse{ + Namespace: sp.Config.Kubernetes.SystemNamespace, + PodName: "none", + ContainerName: "none", + }) + return + } + + for _, pod := range pods { + // find all pod list in right node + if nodeName == pod.Spec.NodeName { + // find the openvswitch-exec pod + if strings.HasPrefix(pod.ObjectMeta.Name, "openvswitch-exec") { + podName = pod.ObjectMeta.Name + // openvswitch-exec should only has one container + containerName = pod.Spec.Containers[0].Name + } + } + } + + resp.WriteHeaderAndEntity(http.StatusOK, shellOVSInfoResponse{ + Namespace: sp.Config.Kubernetes.SystemNamespace, + PodName: podName, + ContainerName: containerName, + }) +} diff --git a/src/server/handler_network_test.go b/src/server/handler_network_test.go index 68228f28..c75ed2e2 100644 --- a/src/server/handler_network_test.go +++ b/src/server/handler_network_test.go @@ -476,3 +476,14 @@ func (suite *NetworkTestSuite) TestListNetworkWithInvalidPage() { suite.wc.Dispatch(httpWriter, httpRequest) assertResponseCode(suite.T(), http.StatusInternalServerError, httpWriter) } + +func (suite *NetworkTestSuite) TestGetOVSShellInfoNotFound() { + notFoundNodeName := "node-55" + httpRequest, err := http.NewRequest("GET", "http://localhost:7890/v1/networks/"+notFoundNodeName+"/shell", nil) + suite.NoError(err) + httpRequest.Header.Add("Authorization", suite.JWTBearer) + + httpWriter := httptest.NewRecorder() + suite.wc.Dispatch(httpWriter, httpRequest) + assertResponseCode(suite.T(), http.StatusNotFound, httpWriter) +} diff --git a/src/server/route.go b/src/server/route.go index feb02a27..22e7ccab 100644 --- a/src/server/route.go +++ b/src/server/route.go @@ -79,6 +79,7 @@ func newNetworkService(sp *serviceprovider.Container) *restful.WebService { webService.Route(webService.GET("/status/{id}").To(handler.RESTfulServiceHandler(sp, getNetworkStatusHandler))) webService.Route(webService.POST("/").To(handler.RESTfulServiceHandler(sp, createNetworkHandler))) webService.Route(webService.DELETE("/{id}").To(handler.RESTfulServiceHandler(sp, deleteNetworkHandler))) + webService.Route(webService.GET("/{node}/shell").To(handler.RESTfulServiceHandler(sp, getOVSShellInfoHandler))) return webService }