mirror of
https://github.com/luscis/openlan.git
synced 2025-10-05 16:47:11 +08:00
fea: support rate limit.
This commit is contained in:
@@ -39,4 +39,5 @@ func Commands(app *api.App) {
|
|||||||
Version{}.Commands(app)
|
Version{}.Commands(app)
|
||||||
Log{}.Commands(app)
|
Log{}.Commands(app)
|
||||||
ZTrust{}.Commands(app)
|
ZTrust{}.Commands(app)
|
||||||
|
Rate{}.Commands(app)
|
||||||
}
|
}
|
||||||
|
92
cmd/api/v5/rate.go
Executable file
92
cmd/api/v5/rate.go
Executable file
@@ -0,0 +1,92 @@
|
|||||||
|
package v5
|
||||||
|
|
||||||
|
import (
|
||||||
|
"github.com/luscis/openlan/cmd/api"
|
||||||
|
"github.com/luscis/openlan/pkg/schema"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Rate struct {
|
||||||
|
Cmd
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u Rate) Url(prefix, name string) string {
|
||||||
|
return prefix + "/api/interface/" + name + "/rate"
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u Rate) Tmpl() string {
|
||||||
|
return `# total {{ len . }}
|
||||||
|
{{ps -16 "device"}} {{ps -8 "speed"}}
|
||||||
|
{{- range . }}
|
||||||
|
{{ps -16 .Device}} {{pi .Speed}}
|
||||||
|
{{- end }}
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u Rate) List(c *cli.Context) error {
|
||||||
|
url := u.Url(c.String("url"), "")
|
||||||
|
clt := u.NewHttp(c.String("token"))
|
||||||
|
var items []schema.Rate
|
||||||
|
if err := clt.GetJSON(url, &items); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return u.Out(items, c.String("format"), u.Tmpl())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u Rate) Add(c *cli.Context) error {
|
||||||
|
name := c.String("device")
|
||||||
|
rate := &schema.Rate{
|
||||||
|
Device: name,
|
||||||
|
Speed: c.Int("speed"),
|
||||||
|
}
|
||||||
|
url := u.Url(c.String("url"), name)
|
||||||
|
clt := u.NewHttp(c.String("token"))
|
||||||
|
if err := clt.PostJSON(url, rate, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u Rate) Remove(c *cli.Context) error {
|
||||||
|
name := c.String("device")
|
||||||
|
|
||||||
|
url := u.Url(c.String("url"), name)
|
||||||
|
clt := u.NewHttp(c.String("token"))
|
||||||
|
if err := clt.DeleteJSON(url, nil, nil); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (u Rate) Commands(app *api.App) {
|
||||||
|
app.Command(&cli.Command{
|
||||||
|
Name: "rate",
|
||||||
|
Usage: "Rate Limit",
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
{
|
||||||
|
Name: "list",
|
||||||
|
Usage: "Display all rate limits",
|
||||||
|
Aliases: []string{"ls"},
|
||||||
|
Action: u.List,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "add",
|
||||||
|
Usage: "Add a rate limit",
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "device", Required: true},
|
||||||
|
&cli.StringFlag{Name: "speed", Required: true},
|
||||||
|
},
|
||||||
|
Action: u.Add,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "remove",
|
||||||
|
Usage: "Remove a rate limit",
|
||||||
|
Aliases: []string{"rm"},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{Name: "device", Required: true},
|
||||||
|
},
|
||||||
|
Action: u.Remove,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
@@ -9,6 +9,11 @@ import (
|
|||||||
"github.com/luscis/openlan/pkg/schema"
|
"github.com/luscis/openlan/pkg/schema"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Rater interface {
|
||||||
|
AddRate(device string, mbit int)
|
||||||
|
DelRate(device string)
|
||||||
|
}
|
||||||
|
|
||||||
type Switcher interface {
|
type Switcher interface {
|
||||||
UUID() string
|
UUID() string
|
||||||
UpTime() int64
|
UpTime() int64
|
||||||
@@ -20,6 +25,7 @@ type Switcher interface {
|
|||||||
AddNetwork(network string)
|
AddNetwork(network string)
|
||||||
DelNetwork(network string)
|
DelNetwork(network string)
|
||||||
SaveNetwork(network string)
|
SaveNetwork(network string)
|
||||||
|
Rater
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewWorkerSchema(s Switcher) schema.Worker {
|
func NewWorkerSchema(s Switcher) schema.Worker {
|
||||||
@@ -89,8 +95,6 @@ type Super interface {
|
|||||||
Start(v Switcher)
|
Start(v Switcher)
|
||||||
Stop()
|
Stop()
|
||||||
Reload(v Switcher)
|
Reload(v Switcher)
|
||||||
DoZTrust()
|
|
||||||
UndoZTrust()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Networker interface {
|
type Networker interface {
|
||||||
@@ -108,6 +112,8 @@ type Networker interface {
|
|||||||
Qoser() Qoser
|
Qoser() Qoser
|
||||||
ACLer() ACLer
|
ACLer() ACLer
|
||||||
FindHoper() FindHoper
|
FindHoper() FindHoper
|
||||||
|
DoZTrust()
|
||||||
|
UndoZTrust()
|
||||||
}
|
}
|
||||||
|
|
||||||
type IPSecer interface {
|
type IPSecer interface {
|
||||||
|
35
pkg/api/rate.go
Executable file
35
pkg/api/rate.go
Executable file
@@ -0,0 +1,35 @@
|
|||||||
|
package api
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/gorilla/mux"
|
||||||
|
"github.com/luscis/openlan/pkg/schema"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Rate struct {
|
||||||
|
Switcher Switcher
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Rate) Router(router *mux.Router) {
|
||||||
|
router.HandleFunc("/api/interface/{id}/rate", h.Post).Methods("POST")
|
||||||
|
router.HandleFunc("/api/interface/{id}/rate", h.Delete).Methods("DELETE")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Rate) Post(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
device := vars["id"]
|
||||||
|
|
||||||
|
rate := &schema.Rate{}
|
||||||
|
if err := GetData(r, rate); err != nil {
|
||||||
|
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
h.Switcher.AddRate(device, rate.Speed)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h Rate) Delete(w http.ResponseWriter, r *http.Request) {
|
||||||
|
vars := mux.Vars(r)
|
||||||
|
device := vars["id"]
|
||||||
|
h.Switcher.DelRate(device)
|
||||||
|
}
|
@@ -14,7 +14,6 @@ func Add(router *mux.Router, switcher Switcher) {
|
|||||||
Device{}.Router(router)
|
Device{}.Router(router)
|
||||||
VPNClient{}.Router(router)
|
VPNClient{}.Router(router)
|
||||||
PProf{}.Router(router)
|
PProf{}.Router(router)
|
||||||
VxLAN{}.Router(router)
|
|
||||||
Config{Switcher: switcher}.Router(router)
|
Config{Switcher: switcher}.Router(router)
|
||||||
Version{}.Router(router)
|
Version{}.Router(router)
|
||||||
Log{}.Router(router)
|
Log{}.Router(router)
|
||||||
@@ -26,4 +25,5 @@ func Add(router *mux.Router, switcher Switcher) {
|
|||||||
Route{Switcher: switcher}.Router(router)
|
Route{Switcher: switcher}.Router(router)
|
||||||
IPSec{}.Router(router)
|
IPSec{}.Router(router)
|
||||||
FindHop{}.Router(router)
|
FindHop{}.Router(router)
|
||||||
|
Rate{Switcher: switcher}.Router(router)
|
||||||
}
|
}
|
||||||
|
@@ -1,20 +0,0 @@
|
|||||||
package api
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
|
||||||
)
|
|
||||||
|
|
||||||
type VxLAN struct {
|
|
||||||
Switcher Switcher
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l VxLAN) Router(router *mux.Router) {
|
|
||||||
router.HandleFunc("/api/vxlan", l.List).Methods("GET")
|
|
||||||
router.HandleFunc("/api/vxlan/{id}", l.List).Methods("GET")
|
|
||||||
}
|
|
||||||
|
|
||||||
func (l VxLAN) List(w http.ResponseWriter, r *http.Request) {
|
|
||||||
ResponseJson(w, nil)
|
|
||||||
}
|
|
6
pkg/schema/rate.go
Normal file
6
pkg/schema/rate.go
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
package schema
|
||||||
|
|
||||||
|
type Rate struct {
|
||||||
|
Device string `json:"device"`
|
||||||
|
Speed int `json:"speed"` // Mbit
|
||||||
|
}
|
@@ -2,6 +2,7 @@ package cswitch
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@@ -599,3 +600,21 @@ func (v *Switch) Reload() {
|
|||||||
func (v *Switch) Save() {
|
func (v *Switch) Save() {
|
||||||
v.cfg.Save()
|
v.cfg.Save()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *Switch) AddRate(device string, mbit int) {
|
||||||
|
kbits := fmt.Sprintf("%dMbit", mbit)
|
||||||
|
burst := "64Kb"
|
||||||
|
latency := "400ms"
|
||||||
|
|
||||||
|
out, err := libol.Exec("tc", "qdisc", "add", "dev", device, "root", "tbf", "rate", kbits, "burst", burst, "latency", latency)
|
||||||
|
if err != nil {
|
||||||
|
v.out.Warn("Switch.AddRate: %s %d %s", device, mbit, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (v *Switch) DelRate(device string) {
|
||||||
|
out, err := libol.Exec("tc", "qdisc", "del", "dev", device, "root")
|
||||||
|
if err != nil {
|
||||||
|
v.out.Warn("Switch.AddRate: %s %s", device, out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user