diff --git a/cmd/api/out.go b/cmd/api/out.go index 3f5e320..6dd65d0 100755 --- a/cmd/api/out.go +++ b/cmd/api/out.go @@ -2,11 +2,12 @@ package api import ( "fmt" - "github.com/ghodss/yaml" - "github.com/luscis/openlan/pkg/libol" "os" "strconv" "text/template" + + "github.com/ghodss/yaml" + "github.com/luscis/openlan/pkg/libol" ) func OutJson(data interface{}) error { @@ -61,6 +62,9 @@ func OutTable(data interface{}, tmpl string) error { } return fmt.Sprintf(format, value) }, + "ut": func(value int64) string { + return libol.UnixTime(value) + }, } if tmpl, err := template.New("main").Funcs(funcMap).Parse(tmpl); err != nil { return err diff --git a/cmd/api/v5/knock.go b/cmd/api/v5/knock.go index fcf2165..703f307 100755 --- a/cmd/api/v5/knock.go +++ b/cmd/api/v5/knock.go @@ -15,7 +15,7 @@ type Knock struct { func (u Knock) Url(prefix, name string) string { name, network := api.SplitName(name) - return prefix + "/api/ztrust/" + network + "/guest/" + name + "/knock" + return prefix + "/api/network/" + network + "/guest/" + name + "/knock" } func (u Knock) Add(c *cli.Context) error { @@ -25,7 +25,7 @@ func (u Knock) Add(c *cli.Context) error { } socket := c.String("socket") knock := &schema.KnockRule{ - Protocl: c.String("protocol"), + Protocol: c.String("protocol"), } knock.Name, knock.Network = api.SplitName(username) knock.Dest, knock.Port = api.SplitSocket(socket) @@ -45,7 +45,7 @@ func (u Knock) Remove(c *cli.Context) error { } socket := c.String("socket") knock := &schema.KnockRule{ - Protocl: c.String("protocol"), + Protocol: c.String("protocol"), } knock.Name, knock.Network = api.SplitName(username) knock.Dest, knock.Port = api.SplitSocket(socket) @@ -60,15 +60,25 @@ func (u Knock) Remove(c *cli.Context) error { func (u Knock) Tmpl() string { return `# total {{ len . }} -{{ps -24 "username"}} {{ps -24 "address"}} +{{ps -24 "username"}} {{ps -8 "protocol"}} {{ps -24 "socket"}} {{ps -24 "createAt"}} {{- range . }} -{{p2 -24 "%s@%s" .Name .Network}} {{ps -24 .Address}} +{{p2 -24 "%s@%s" .Name .Network}} {{ps -8 .Protocol}} {{p2 -24 "%s:%s" .Dest .Port}} {{ut .CreateAt}} {{- end }} ` } func (u Knock) List(c *cli.Context) error { - return nil + name := c.String("name") + + url := u.Url(c.String("url"), name) + clt := u.NewHttp(c.String("token")) + + var items []schema.KnockRule + if err := clt.GetJSON(url, &items); err != nil { + return err + } + + return u.Out(items, c.String("format"), u.Tmpl()) } func (u Knock) Commands(app *api.App) { @@ -103,7 +113,7 @@ func (u Knock) Commands(app *api.App) { Usage: "Display all knock", Aliases: []string{"ls"}, Flags: []cli.Flag{ - &cli.StringFlag{Name: "network"}, + &cli.StringFlag{Name: "name"}, }, Action: u.List, }, diff --git a/cmd/api/v5/zguest.go b/cmd/api/v5/zguest.go index 14a13ce..ed1da69 100755 --- a/cmd/api/v5/zguest.go +++ b/cmd/api/v5/zguest.go @@ -16,10 +16,9 @@ type ZGuest struct { func (u ZGuest) Url(prefix, name string) string { name, network := api.SplitName(name) if name == "" { - return prefix + "/api/ztrust/" + network + "/guest" - } else { - return prefix + "/api/ztrust/" + network + "/guest/" + name + return prefix + "/api/network/" + network + "/guest" } + return prefix + "/api/network/" + network + "/guest/" + name } func (u ZGuest) Add(c *cli.Context) error { @@ -68,7 +67,17 @@ func (u ZGuest) Tmpl() string { } func (u ZGuest) List(c *cli.Context) error { - return nil + network := c.String("network") + + url := u.Url(c.String("url"), "@"+network) + clt := u.NewHttp(c.String("token")) + + var items []schema.ZGuest + if err := clt.GetJSON(url, &items); err != nil { + return err + } + + return u.Out(items, c.String("format"), u.Tmpl()) } func (u ZGuest) Commands(app *api.App) { diff --git a/pkg/api/switcher.go b/pkg/api/api.go similarity index 92% rename from pkg/api/switcher.go rename to pkg/api/api.go index 2a8b59b..45d9060 100755 --- a/pkg/api/switcher.go +++ b/pkg/api/api.go @@ -34,6 +34,8 @@ type ZTruster interface { AddGuest(name, source string) error DelGuest(name, source string) error Knock(name string, protocol, dest, port string, age int) error + ListGuest(call func(obj schema.ZGuest)) + ListKnock(name string, call func(obj schema.KnockRule)) } type Networker interface { diff --git a/pkg/api/vxlan.go b/pkg/api/vxlan.go index e7e0db6..35d294d 100755 --- a/pkg/api/vxlan.go +++ b/pkg/api/vxlan.go @@ -1,8 +1,9 @@ package api import ( - "github.com/gorilla/mux" "net/http" + + "github.com/gorilla/mux" ) type VxLAN struct { diff --git a/pkg/api/ztrust.go b/pkg/api/ztrust.go index b6dca98..7082913 100755 --- a/pkg/api/ztrust.go +++ b/pkg/api/ztrust.go @@ -13,13 +13,12 @@ type ZTrust struct { } func (h ZTrust) Router(router *mux.Router) { - router.HandleFunc("/api/ztrust", h.List).Methods("GET") - router.HandleFunc("/api/ztrust/{id}", h.Get).Methods("GET") - router.HandleFunc("/api/ztrust/{id}/guest/{user}", h.GetGuest).Methods("GET") - router.HandleFunc("/api/ztrust/{id}/guest/{user}", h.AddGuest).Methods("POST") - router.HandleFunc("/api/ztrust/{id}/guest/{user}", h.DelGuest).Methods("DELETE") - router.HandleFunc("/api/ztrust/{id}/guest/{user}/knock", h.ListKnock).Methods("GET") - router.HandleFunc("/api/ztrust/{id}/guest/{user}/knock", h.AddKnock).Methods("POST") + router.HandleFunc("/api/network/{id}/ztrust", h.List).Methods("GET") + router.HandleFunc("/api/network/{id}/guest", h.ListGuest).Methods("GET") + router.HandleFunc("/api/network/{id}/guest/{user}", h.AddGuest).Methods("POST") + router.HandleFunc("/api/network/{id}/guest/{user}", h.DelGuest).Methods("DELETE") + router.HandleFunc("/api/network/{id}/guest/{user}/knock", h.ListKnock).Methods("GET") + router.HandleFunc("/api/network/{id}/guest/{user}/knock", h.AddKnock).Methods("POST") } func (h ZTrust) List(w http.ResponseWriter, r *http.Request) { @@ -32,10 +31,27 @@ func (h ZTrust) Get(w http.ResponseWriter, r *http.Request) { ResponseJson(w, "TODO") } -func (h ZTrust) GetGuest(w http.ResponseWriter, r *http.Request) { +func (h ZTrust) ListGuest(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - libol.Info("ZTrust.AddGuest %s", vars["id"]) - ResponseJson(w, "TODO") + id := vars["id"] + + worker := GetWorker(id) + if worker == nil { + http.Error(w, "Network not found", http.StatusInternalServerError) + return + } + ztrust := worker.ZTruster() + if ztrust == nil { + http.Error(w, "ZTrust disabled", http.StatusInternalServerError) + return + } + + guests := make([]schema.ZGuest, 0, 1024) + ztrust.ListGuest(func(obj schema.ZGuest) { + guests = append(guests, obj) + }) + + ResponseJson(w, guests) } func (h ZTrust) AddGuest(w http.ResponseWriter, r *http.Request) { @@ -103,13 +119,30 @@ func (h ZTrust) DelGuest(w http.ResponseWriter, r *http.Request) { func (h ZTrust) ListKnock(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - libol.Info("ZTrust.ListKnock %s", vars["id"]) - ResponseJson(w, "TODO") + id := vars["id"] + + worker := GetWorker(id) + if worker == nil { + http.Error(w, "Network not found", http.StatusInternalServerError) + return + } + ztrust := worker.ZTruster() + if ztrust == nil { + http.Error(w, "ZTrust disabled", http.StatusInternalServerError) + return + } + + name := vars["user"] + rules := make([]schema.KnockRule, 0, 1024) + ztrust.ListKnock(name, func(obj schema.KnockRule) { + rules = append(rules, obj) + }) + + ResponseJson(w, rules) } func (h ZTrust) AddKnock(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) - id := vars["id"] worker := GetWorker(id) @@ -131,7 +164,7 @@ func (h ZTrust) AddKnock(w http.ResponseWriter, r *http.Request) { name := vars["user"] libol.Info("ZTrust.AddKnock %s@%s", rule.Name, id) - if err := ztrust.Knock(name, rule.Protocl, rule.Dest, rule.Port, 0); err == nil { + if err := ztrust.Knock(name, rule.Protocol, rule.Dest, rule.Port, 0); err == nil { ResponseJson(w, "success") } else { http.Error(w, err.Error(), http.StatusInternalServerError) diff --git a/pkg/libol/utils.go b/pkg/libol/utils.go index 8096fb9..dc5ef6b 100755 --- a/pkg/libol/utils.go +++ b/pkg/libol/utils.go @@ -192,6 +192,10 @@ func IPNetwork(ipAddr string) (string, error) { } } +func UnixTime(value int64) string { + return time.Unix(value, 0).UTC().String() +} + func PrettyTime(t int64) string { s := "" if t < 0 { diff --git a/pkg/schema/ztrust.go b/pkg/schema/ztrust.go index 367d6a3..9a930c3 100755 --- a/pkg/schema/ztrust.go +++ b/pkg/schema/ztrust.go @@ -8,10 +8,11 @@ type ZGuest struct { } type KnockRule struct { - Network string `json:"network"` - Name string `json:"name"` - Dest string `json:"destination"` - Protocl string `json:"protocol"` - Port string `json:"port"` - Age int `json:"age"` + Network string `json:"network"` + Name string `json:"name"` + Dest string `json:"destination"` + Protocol string `json:"protocol"` + Port string `json:"port"` + Age int `json:"age"` + CreateAt int64 `json:"createAt"` } diff --git a/pkg/switch/ztrust.go b/pkg/switch/ztrust.go index 9e007b6..7dcb03f 100644 --- a/pkg/switch/ztrust.go +++ b/pkg/switch/ztrust.go @@ -7,6 +7,7 @@ import ( "github.com/luscis/openlan/pkg/libol" "github.com/luscis/openlan/pkg/network" cn "github.com/luscis/openlan/pkg/network" + "github.com/luscis/openlan/pkg/schema" ) type KnockRule struct { @@ -215,3 +216,35 @@ func (z *ZTrust) Stop() { guest.Stop() } } + +func (z *ZTrust) ListGuest(call func(obj schema.ZGuest)) { + for _, guest := range z.guests { + for _, source := range guest.sources { + obj := schema.ZGuest{ + Name: guest.username, + Network: guest.network, + Address: source, + } + call(obj) + } + } +} + +func (z *ZTrust) ListKnock(name string, call func(obj schema.KnockRule)) { + guest, ok := z.guests[name] + if !ok { + return + } + + for _, rule := range guest.rules { + obj := schema.KnockRule{ + Name: name, + Network: z.network, + Protocol: rule.protocol, + Dest: rule.destination, + Port: rule.port, + CreateAt: rule.createAt, + } + call(obj) + } +}