Skip to content

Commit

Permalink
add and delete apis
Browse files Browse the repository at this point in the history
Signed-off-by: Atul-source <[email protected]>
  • Loading branch information
Atul-source committed Aug 15, 2022
1 parent 5257289 commit 4ecf327
Show file tree
Hide file tree
Showing 14 changed files with 1,654 additions and 48 deletions.
72 changes: 72 additions & 0 deletions apis/handlers/addprog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright Contributors to the L3AF Project.
// SPDX-License-Identifier: Apache-2.0

package handlers

import (
"context"
"encoding/json"
"fmt"

"io/ioutil"
"net/http"

"github.com/rs/zerolog/log"

"github.com/l3af-project/l3afd/kf"
"github.com/l3af-project/l3afd/models"
)

// AddEbpfPrograms add new eBPF programs on node
// @Summary Adding new eBPF Programs on node
// @Description Adding new eBPF Programs on node
// @Accept json
// @Produce json
// @Param cfgs body []models.L3afBPFPrograms true "BPF programs"
// @Success 200
// @Router /l3af/configs/v1/add [post]
func AddEbpfPrograms(ctx context.Context, kfcfg *kf.NFConfigs) http.HandlerFunc {

return func(w http.ResponseWriter, r *http.Request) {
mesg := ""
statusCode := http.StatusOK

w.Header().Add("Content-Type", "application/json")

defer func(mesg *string, statusCode *int) {
w.WriteHeader(*statusCode)
_, err := w.Write([]byte(*mesg))
if err != nil {
log.Warn().Msgf("Failed to write response bytes: %v", err)
}
}(&mesg, &statusCode)

if r.Body == nil {
log.Warn().Msgf("Empty request body")
return
}
bodyBuffer, err := ioutil.ReadAll(r.Body)
if err != nil {
mesg = fmt.Sprintf("failed to read request body: %v", err)
log.Error().Msg(mesg)
statusCode = http.StatusInternalServerError
return
}

var t []models.L3afBPFPrograms
if err := json.Unmarshal(bodyBuffer, &t); err != nil {
mesg = fmt.Sprintf("failed to unmarshal payload: %v", err)
log.Error().Msg(mesg)
statusCode = http.StatusInternalServerError
return
}

if err := kfcfg.AddeBPFPrograms(t); err != nil {
mesg = fmt.Sprintf("failed to AddeBPFPrograms : %v", err)
log.Error().Msg(mesg)

statusCode = http.StatusInternalServerError
return
}
}
}
104 changes: 104 additions & 0 deletions apis/handlers/addprog_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
package handlers

import (
"context"
"net/http"
"net/http/httptest"
"path/filepath"
"strings"
"testing"

"github.com/l3af-project/l3afd/config"
"github.com/l3af-project/l3afd/kf"
)

const dummypayload string = `[
{
"host_name" : "l3af-local-test",
"iface" : "fakeif0",
"bpf_programs" : {
"xdp_ingress" : [
],
"tc_egress": [
],
"tc_ingress": [
]
}
}
]
`

func Test_addprog(t *testing.T) {

tests := []struct {
name string
Body *strings.Reader
header map[string]string
status int
cfg *kf.NFConfigs
}{
{
name: "NilBody",
Body: nil,
status: http.StatusOK,
cfg: &kf.NFConfigs{
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
},
{
name: "FailedToUnmarshal",
Body: strings.NewReader("Something"),
status: http.StatusInternalServerError,
header: map[string]string{},
cfg: &kf.NFConfigs{
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
},
{
name: "EmptyInput",
Body: strings.NewReader("[]"),
header: map[string]string{
"Content-Type": "application/json",
},
cfg: &kf.NFConfigs{
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
status: http.StatusOK,
},
{
name: "UnknownHostName",
Body: strings.NewReader(dummypayload),
status: http.StatusInternalServerError,
header: map[string]string{},
cfg: &kf.NFConfigs{
HostName: "dummy",
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
},
}
for _, tt := range tests {
var req *http.Request
if tt.Body == nil {
req, _ = http.NewRequest("POST", "/l3af/configs/v1/add", nil)
} else {
req, _ = http.NewRequest("POST", "/l3af/configs/v1/add", tt.Body)
}
for key, val := range tt.header {
req.Header.Set(key, val)
}
rr := httptest.NewRecorder()
handler := AddEbpfPrograms(context.Background(), tt.cfg)
handler.ServeHTTP(rr, req)
if rr.Code != tt.status {
t.Error("AddEbpfPrograms Failed")
}
}
}
72 changes: 72 additions & 0 deletions apis/handlers/deleteprog.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Copyright Contributors to the L3AF Project.
// SPDX-License-Identifier: Apache-2.0

package handlers

import (
"context"
"encoding/json"
"fmt"

"io/ioutil"
"net/http"

"github.com/rs/zerolog/log"

"github.com/l3af-project/l3afd/kf"
"github.com/l3af-project/l3afd/models"
)

// DeleteEbpfPrograms remove eBPF programs on node
// @Summary remove eBPF Programs on node
// @Description remove eBPF Programs on node
// @Accept json
// @Produce json
// @Param cfgs body []models.L3afBPFProgramNames true "BPF program names"
// @Success 200
// @Router /l3af/configs/v1/delete [post]
func DeleteEbpfPrograms(ctx context.Context, kfcfg *kf.NFConfigs) http.HandlerFunc {

return func(w http.ResponseWriter, r *http.Request) {
mesg := ""
statusCode := http.StatusOK

w.Header().Add("Content-Type", "application/json")

defer func(mesg *string, statusCode *int) {
w.WriteHeader(*statusCode)
_, err := w.Write([]byte(*mesg))
if err != nil {
log.Warn().Msgf("Failed to write response bytes: %v", err)
}
}(&mesg, &statusCode)

if r.Body == nil {
log.Warn().Msgf("Empty request body")
return
}
bodyBuffer, err := ioutil.ReadAll(r.Body)
if err != nil {
mesg = fmt.Sprintf("failed to read request body: %v", err)
log.Error().Msg(mesg)
statusCode = http.StatusInternalServerError
return
}

var t []models.L3afBPFProgramNames
if err := json.Unmarshal(bodyBuffer, &t); err != nil {
mesg = fmt.Sprintf("failed to unmarshal payload: %v", err)
log.Error().Msg(mesg)
statusCode = http.StatusInternalServerError
return
}

if err := kfcfg.DeleteEbpfPrograms(t); err != nil {
mesg = fmt.Sprintf("failed to DeleteEbpfPrograms : %v", err)
log.Error().Msg(mesg)

statusCode = http.StatusInternalServerError
return
}
}
}
102 changes: 102 additions & 0 deletions apis/handlers/deleteprog_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package handlers

import (
"context"
"net/http"
"net/http/httptest"
"path/filepath"
"strings"
"testing"

"github.com/l3af-project/l3afd/config"
"github.com/l3af-project/l3afd/kf"
)

const payloadfordelete string = `[
{
"host_name": "l3af-local-test",
"iface": "fakeif0",
"bpf_programs": {
"xdp_ingress": [
"ratelimiting",
"connection-limit"
]
}
}
]
`

func Test_DeleteEbpfPrograms(t *testing.T) {

tests := []struct {
name string
Body *strings.Reader
header map[string]string
status int
cfg *kf.NFConfigs
}{
{
name: "NilBody",
Body: nil,
status: http.StatusOK,
cfg: &kf.NFConfigs{
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
},
{
name: "FailedToUnmarshal",
Body: strings.NewReader("Something"),
status: http.StatusInternalServerError,
header: map[string]string{},
cfg: &kf.NFConfigs{
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
},
{
name: "EmptyInput",
Body: strings.NewReader(`[]`),
header: map[string]string{
"Content-Type": "application/json",
},
cfg: &kf.NFConfigs{
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
status: http.StatusOK,
},
{
name: "UnknownHostName",
Body: strings.NewReader(payloadfordelete),
status: http.StatusInternalServerError,
header: map[string]string{},
cfg: &kf.NFConfigs{
HostName: "dummy",
HostConfig: &config.Config{
L3afConfigStoreFileName: filepath.FromSlash("../../testdata/Test_l3af-config.json"),
},
},
},
}
for _, tt := range tests {
var req *http.Request
if tt.Body == nil {
req, _ = http.NewRequest("POST", "/l3af/configs/v1/delete", nil)
} else {
req, _ = http.NewRequest("POST", "/l3af/configs/v1/delete", tt.Body)
}
for key, val := range tt.header {
req.Header.Set(key, val)
}
rr := httptest.NewRecorder()
handler := DeleteEbpfPrograms(context.Background(), tt.cfg)
handler.ServeHTTP(rr, req)
if rr.Code != tt.status {
t.Error("DeleteEbpfPrograms Failed")
}
}
}
Loading

0 comments on commit 4ecf327

Please sign in to comment.