Refactor UI with vue3

This commit is contained in:
cuigh
2021-12-06 20:24:22 +08:00
parent afbc618abb
commit 2dd9cd15e1
411 changed files with 22726 additions and 69351 deletions

38
api/api.go Normal file
View File

@@ -0,0 +1,38 @@
package api
import (
"github.com/cuigh/auxo/app/container"
"github.com/cuigh/auxo/net/web"
)
func ajax(ctx web.Context, err error) error {
if err != nil {
return err
}
return success(ctx, nil)
}
func success(ctx web.Context, data interface{}) error {
return ctx.Result(0, "", data)
}
func init() {
container.Put(NewSystem, container.Name("api.system"))
container.Put(NewSetting, container.Name("api.setting"))
container.Put(NewUser, container.Name("api.user"))
container.Put(NewNode, container.Name("api.node"))
container.Put(NewRegistry, container.Name("api.registry"))
container.Put(NewNetwork, container.Name("api.network"))
container.Put(NewService, container.Name("api.service"))
container.Put(NewTask, container.Name("api.task"))
container.Put(NewConfig, container.Name("api.config"))
container.Put(NewSecret, container.Name("api.secret"))
container.Put(NewStack, container.Name("api.stack"))
container.Put(NewImage, container.Name("api.image"))
container.Put(NewContainer, container.Name("api.container"))
container.Put(NewVolume, container.Name("api.volume"))
container.Put(NewUser, container.Name("api.user"))
container.Put(NewRole, container.Name("api.role"))
container.Put(NewEvent, container.Name("api.event"))
container.Put(NewChart, container.Name("api.chart"))
}

159
api/chart.go Normal file
View File

@@ -0,0 +1,159 @@
package api
import (
"strings"
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/errors"
"github.com/cuigh/auxo/ext/times"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
"github.com/cuigh/swirl/model"
)
// ChartHandler encapsulates chart related handlers.
type ChartHandler struct {
Search web.HandlerFunc `path:"/search" auth:"chart.view" desc:"search charts"`
Find web.HandlerFunc `path:"/find" auth:"chart.view" desc:"find chart by id"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"chart.edit" desc:"create or update chart"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"chart.delete" desc:"delete chart"`
FetchData web.HandlerFunc `path:"/fetch-data" auth:"?" desc:"fetch chart data"`
FindDashboard web.HandlerFunc `path:"/find-dashboard" auth:"?" desc:"find dashboard by name and key"`
SaveDashboard web.HandlerFunc `path:"/save-dashboard" method:"post" auth:"chart.dashboard" desc:"save dashboard"`
}
// NewChart creates an instance of ChartHandler
func NewChart(b biz.ChartBiz) *ChartHandler {
return &ChartHandler{
Search: chartSearch(b),
Find: chartFind(b),
Delete: chartDelete(b),
Save: chartSave(b),
FetchData: chartFetchData(b),
FindDashboard: chartFindDashboard(b),
SaveDashboard: chartSaveDashboard(b),
}
}
func chartSearch(b biz.ChartBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
Dashboard string `json:"dashboard" bind:"dashboard"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
charts []*biz.Chart
total int
)
if err = ctx.Bind(args); err == nil {
charts, total, err = b.Search(args.Name, args.Dashboard, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": charts,
"total": total,
})
}
}
func chartFind(b biz.ChartBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
chart, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, chart)
}
}
func chartDelete(b biz.ChartBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Title string `json:"title"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.ID, args.Title, ctx.User())
}
return ajax(ctx, err)
}
}
func chartSave(b biz.ChartBiz) web.HandlerFunc {
return func(ctx web.Context) error {
r := &model.Chart{}
err := ctx.Bind(r, true)
if err == nil {
if r.ID == "" {
err = b.Create(r, ctx.User())
} else {
err = b.Update(r, ctx.User())
}
}
return ajax(ctx, err)
}
}
func chartFetchData(b biz.ChartBiz) web.HandlerFunc {
type Args struct {
Key string `json:"key" bind:"key"`
Charts string `json:"charts" bind:"charts"`
Period int32 `json:"period" bind:"period"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
d data.Map
)
if err = ctx.Bind(args); err == nil {
d, err = b.FetchData(args.Key, strings.Split(args.Charts, ","), times.Minutes(args.Period))
}
if err != nil {
return err
}
return success(ctx, d)
}
}
func chartFindDashboard(b biz.ChartBiz) web.HandlerFunc {
return func(ctx web.Context) (err error) {
var (
d *biz.Dashboard
name = ctx.Query("name")
key = ctx.Query("key")
)
d, err = b.FindDashboard(name, key)
if err != nil {
return err
}
return success(ctx, d)
}
}
func chartSaveDashboard(b biz.ChartBiz) web.HandlerFunc {
return func(ctx web.Context) error {
dashboard := &model.Dashboard{}
err := ctx.Bind(dashboard)
if err != nil {
return err
}
switch dashboard.Name {
case "home", "service":
err = b.UpdateDashboard(dashboard, ctx.User())
default:
err = errors.New("unknown dashboard: " + dashboard.Name)
}
return ajax(ctx, err)
}
}

94
api/config.go Normal file
View File

@@ -0,0 +1,94 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// ConfigHandler encapsulates config related handlers.
type ConfigHandler struct {
Search web.HandlerFunc `path:"/search" auth:"config.view" desc:"search configs"`
Find web.HandlerFunc `path:"/find" auth:"config.view" desc:"find config by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"config.delete" desc:"delete config"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"config.edit" desc:"create or update config"`
}
// NewConfig creates an instance of ConfigHandler
func NewConfig(b biz.ConfigBiz) *ConfigHandler {
return &ConfigHandler{
Search: configSearch(b),
Find: configFind(b),
Delete: configDelete(b),
Save: configSave(b),
}
}
func configSearch(b biz.ConfigBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
configs []*biz.Config
total int
)
if err = ctx.Bind(args); err == nil {
configs, total, err = b.Search(args.Name, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": configs,
"total": total,
})
}
}
func configFind(b biz.ConfigBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
config, raw, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, data.Map{"config": config, "raw": raw})
}
}
func configDelete(b biz.ConfigBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.ID, args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func configSave(b biz.ConfigBiz) web.HandlerFunc {
return func(ctx web.Context) error {
c := &biz.Config{}
err := ctx.Bind(c, true)
if err == nil {
if c.ID == "" {
err = b.Create(c, ctx.User())
} else {
err = b.Update(c, ctx.User())
}
}
return ajax(ctx, err)
}
}

211
api/container.go Normal file
View File

@@ -0,0 +1,211 @@
package api
import (
"io"
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/log"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
"github.com/gobwas/ws"
"github.com/gobwas/ws/wsutil"
)
// ContainerHandler encapsulates container related handlers.
type ContainerHandler struct {
Search web.HandlerFunc `path:"/search" auth:"container.view" desc:"search containers"`
Find web.HandlerFunc `path:"/find" auth:"container.view" desc:"find container by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"container.delete" desc:"delete container"`
FetchLogs web.HandlerFunc `path:"/fetch-logs" auth:"container.logs" desc:"fetch logs of container"`
Connect web.HandlerFunc `path:"/connect" auth:"*" desc:"connect to a running container"`
}
// NewContainer creates an instance of ContainerHandler
func NewContainer(b biz.ContainerBiz) *ContainerHandler {
return &ContainerHandler{
Search: containerSearch(b),
Find: containerFind(b),
Delete: containerDelete(b),
FetchLogs: containerFetchLogs(b),
Connect: containerConnect(b),
}
}
func containerSearch(b biz.ContainerBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
Status string `json:"status" bind:"status"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
containers []*biz.Container
total int
)
if err = ctx.Bind(args); err == nil {
containers, total, err = b.Search(args.Name, args.Status, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": containers,
"total": total,
})
}
}
func containerFind(b biz.ContainerBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
container, raw, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, data.Map{"container": container, "raw": raw})
}
}
func containerDelete(b biz.ContainerBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.ID, ctx.User())
}
return ajax(ctx, err)
}
}
func containerFetchLogs(b biz.ContainerBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id" bind:"id"`
Lines int `json:"lines" bind:"lines"`
Timestamps bool `json:"timestamps" bind:"timestamps"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
stdout, stderr string
)
if err = ctx.Bind(args); err == nil {
stdout, stderr, err = b.FetchLogs(args.ID, args.Lines, args.Timestamps)
}
if err != nil {
return err
}
return success(ctx, data.Map{"stdout": stdout, "stderr": stderr})
}
}
func containerConnect(b biz.ContainerBiz) web.HandlerFunc {
return func(ctx web.Context) error {
var (
id = ctx.Query("id")
cmd = ctx.Query("cmd")
)
_, _, err := b.Find(id)
if err != nil {
return err
}
conn, _, _, err := ws.UpgradeHTTP(ctx.Request(), ctx.Response())
if err != nil {
return err
}
idResp, err := b.ExecCreate(id, cmd)
if err != nil {
return err
}
resp, err := b.ExecAttach(idResp.ID)
if err != nil {
return err
}
err = b.ExecStart(idResp.ID)
if err != nil {
return err
}
var (
closed = false
logger = log.Get("container")
disposer = func() {
if !closed {
closed = true
_ = conn.Close()
resp.Close()
}
}
)
// input
go func() {
defer disposer()
var (
msg []byte
op ws.OpCode
)
for {
msg, op, err = wsutil.ReadClientData(conn)
if err != nil {
if !closed {
logger.Error("failed to read data from client: ", err)
}
break
}
if op == ws.OpClose {
break
}
_, err = resp.Conn.Write(msg)
if err != nil {
logger.Error("failed to write data to container: ", err)
break
}
}
}()
// output
go func() {
defer disposer()
var (
n int
buf = make([]byte, 1024)
)
for {
n, err = resp.Reader.Read(buf)
if err == io.EOF {
break
} else if err != nil {
logger.Error("failed to read data from container: ", err)
break
}
err = wsutil.WriteServerMessage(conn, ws.OpText, buf[:n])
if err != nil {
logger.Error("failed to write data to client: ", err)
break
}
}
}()
return nil
}
}

62
api/event.go Normal file
View File

@@ -0,0 +1,62 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/errors"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
"github.com/cuigh/swirl/model"
)
// EventHandler encapsulates event related handlers.
type EventHandler struct {
Search web.HandlerFunc `path:"/search" auth:"event.view" desc:"search events"`
Prune web.HandlerFunc `path:"/prune" method:"post" auth:"event.delete" desc:"delete events"`
}
// NewEvent creates an instance of EventHandler
func NewEvent(b biz.EventBiz) *EventHandler {
return &EventHandler{
Search: eventSearch(b),
Prune: eventPrune(b),
}
}
func eventSearch(b biz.EventBiz) web.HandlerFunc {
return func(ctx web.Context) (err error) {
var (
args = &model.EventListArgs{}
events []*biz.Event
total int
)
if err = ctx.Bind(args); err == nil {
events, total, err = b.Search(args)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": events,
"total": total,
})
}
}
func eventPrune(b biz.EventBiz) web.HandlerFunc {
type Args struct {
Date string `json:"date"`
}
return func(ctx web.Context) (err error) {
var args = &Args{}
if err = ctx.Bind(args); err == nil {
// TODO
//err = b.Prune(args.Date)
err = errors.NotImplemented
}
return ajax(ctx, err)
}
}

76
api/image.go Normal file
View File

@@ -0,0 +1,76 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// ImageHandler encapsulates image related handlers.
type ImageHandler struct {
Search web.HandlerFunc `path:"/search" auth:"image.view" desc:"search images"`
Find web.HandlerFunc `path:"/find" auth:"image.view" desc:"find image by id"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"image.delete" desc:"delete image"`
}
// NewImage creates an instance of ImageHandler
func NewImage(b biz.ImageBiz) *ImageHandler {
return &ImageHandler{
Search: imageSearch(b),
Find: imageFind(b),
Delete: imageDelete(b),
}
}
func imageSearch(b biz.ImageBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
images []*biz.Image
total int
)
if err = ctx.Bind(args); err == nil {
images, total, err = b.Search(args.Name, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": images,
"total": total,
})
}
}
func imageFind(b biz.ImageBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
image, raw, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, data.Map{"image": image, "raw": raw})
}
}
func imageDelete(b biz.ImageBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.ID, ctx.User())
}
return ajax(ctx, err)
}
}

89
api/network.go Normal file
View File

@@ -0,0 +1,89 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// NetworkHandler encapsulates network related handlers.
type NetworkHandler struct {
Search web.HandlerFunc `path:"/search" auth:"network.view" desc:"search networks"`
Find web.HandlerFunc `path:"/find" auth:"network.view" desc:"find network by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"network.delete" desc:"delete network"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"network.edit" desc:"create or update network"`
Disconnect web.HandlerFunc `path:"/disconnect" method:"post" auth:"network.disconnect" desc:"disconnect container from network"`
}
// NewNetwork creates an instance of NetworkHandler
func NewNetwork(nb biz.NetworkBiz) *NetworkHandler {
return &NetworkHandler{
Search: networkSearch(nb),
Find: networkFind(nb),
Delete: networkDelete(nb),
Save: networkSave(nb),
Disconnect: networkDisconnect(nb),
}
}
func networkSearch(nb biz.NetworkBiz) web.HandlerFunc {
return func(ctx web.Context) error {
networks, err := nb.Search()
if err != nil {
return err
}
return success(ctx, networks)
}
}
func networkFind(nb biz.NetworkBiz) web.HandlerFunc {
return func(ctx web.Context) error {
name := ctx.Query("name")
network, raw, err := nb.Find(name)
if err != nil {
return err
}
return success(ctx, data.Map{"network": network, "raw": raw})
}
}
func networkDelete(nb biz.NetworkBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = nb.Delete(args.ID, args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func networkSave(nb biz.NetworkBiz) web.HandlerFunc {
return func(ctx web.Context) error {
n := &biz.Network{}
err := ctx.Bind(n, true)
if err == nil {
err = nb.Create(n, ctx.User())
}
return ajax(ctx, err)
}
}
func networkDisconnect(nb biz.NetworkBiz) web.HandlerFunc {
type Args struct {
NetworkID string `json:"networkId"`
NetworkName string `json:"networkName"`
Container string `json:"container"`
}
return func(ctx web.Context) error {
args := &Args{}
err := ctx.Bind(args, true)
if err == nil {
err = nb.Disconnect(args.NetworkID, args.NetworkName, args.Container, ctx.User())
}
return ajax(ctx, err)
}
}

72
api/node.go Normal file
View File

@@ -0,0 +1,72 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// NodeHandler encapsulates node related handlers.
type NodeHandler struct {
Search web.HandlerFunc `path:"/search" auth:"node.view" desc:"search nodes"`
Find web.HandlerFunc `path:"/find" auth:"node.view" desc:"find node by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"node.delete" desc:"delete node"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"node.edit" desc:"create or update node"`
}
// NewNode creates an instance of NodeHandler
func NewNode(nb biz.NodeBiz) *NodeHandler {
return &NodeHandler{
Search: nodeSearch(nb),
Find: nodeFind(nb),
Delete: nodeDelete(nb),
Save: nodeSave(nb),
}
}
func nodeSearch(nb biz.NodeBiz) web.HandlerFunc {
return func(ctx web.Context) error {
nodes, err := nb.Search()
if err != nil {
return err
}
return success(ctx, nodes)
}
}
func nodeFind(nb biz.NodeBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
node, raw, err := nb.Find(id)
if err != nil {
return err
}
return success(ctx, data.Map{"node": node, "raw": raw})
}
}
func nodeDelete(nb biz.NodeBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = nb.Delete(args.ID, args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func nodeSave(nb biz.NodeBiz) web.HandlerFunc {
return func(ctx web.Context) error {
n := &biz.Node{}
err := ctx.Bind(n, true)
if err == nil {
err = nb.Update(n, ctx.User())
}
return ajax(ctx, err)
}
}

74
api/registry.go Normal file
View File

@@ -0,0 +1,74 @@
package api
import (
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// RegistryHandler encapsulates registry related handlers.
type RegistryHandler struct {
Search web.HandlerFunc `path:"/search" auth:"registry.view" desc:"search registries"`
Find web.HandlerFunc `path:"/find" auth:"registry.view" desc:"find registry by id"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"registry.delete" desc:"delete registry"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"registry.edit" desc:"create or update registry"`
}
// NewRegistry creates an instance of RegistryHandler
func NewRegistry(b biz.RegistryBiz) *RegistryHandler {
return &RegistryHandler{
Search: registrySearch(b),
Find: registryFind(b),
Delete: registryDelete(b),
Save: registrySave(b),
}
}
func registrySearch(b biz.RegistryBiz) web.HandlerFunc {
return func(ctx web.Context) error {
registries, err := b.Search()
if err != nil {
return err
}
return success(ctx, registries)
}
}
func registryFind(b biz.RegistryBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
node, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, node)
}
}
func registryDelete(b biz.RegistryBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.ID, args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func registrySave(b biz.RegistryBiz) web.HandlerFunc {
return func(ctx web.Context) error {
r := &biz.Registry{}
err := ctx.Bind(r, true)
if err == nil {
if r.ID == "" {
err = b.Create(r, ctx.User())
} else {
err = b.Update(r, ctx.User())
}
}
return ajax(ctx, err)
}
}

75
api/role.go Normal file
View File

@@ -0,0 +1,75 @@
package api
import (
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// RoleHandler encapsulates role related handlers.
type RoleHandler struct {
Find web.HandlerFunc `path:"/find" auth:"role.view" desc:"find role by id"`
Search web.HandlerFunc `path:"/search" auth:"role.view" desc:"search roles"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"role.edit" desc:"create or update role"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"role.delete" desc:"delete role"`
}
// NewRole creates an instance of RoleHandler
func NewRole(b biz.RoleBiz) *RoleHandler {
return &RoleHandler{
Search: roleSearch(b),
Find: roleFind(b),
Delete: roleDelete(b),
Save: roleSave(b),
}
}
func roleSearch(b biz.RoleBiz) web.HandlerFunc {
return func(ctx web.Context) error {
name := ctx.Query("name")
roles, err := b.Search(name)
if err != nil {
return err
}
return success(ctx, roles)
}
}
func roleFind(b biz.RoleBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
role, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, role)
}
}
func roleDelete(b biz.RoleBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.ID, args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func roleSave(b biz.RoleBiz) web.HandlerFunc {
return func(ctx web.Context) error {
r := &biz.Role{}
err := ctx.Bind(r, true)
if err == nil {
if r.ID == "" {
err = b.Create(r, ctx.User())
} else {
err = b.Update(r, ctx.User())
}
}
return ajax(ctx, err)
}
}

94
api/secret.go Normal file
View File

@@ -0,0 +1,94 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// SecretHandler encapsulates secret related handlers.
type SecretHandler struct {
Search web.HandlerFunc `path:"/search" auth:"secret.view" desc:"search secrets"`
Find web.HandlerFunc `path:"/find" auth:"secret.view" desc:"find secret by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"secret.delete" desc:"delete secret"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"secret.edit" desc:"create or update secret"`
}
// NewSecret creates an instance of SecretHandler
func NewSecret(b biz.SecretBiz) *SecretHandler {
return &SecretHandler{
Search: secretSearch(b),
Find: secretFind(b),
Delete: secretDelete(b),
Save: secretSave(b),
}
}
func secretSearch(b biz.SecretBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
secrets []*biz.Secret
total int
)
if err = ctx.Bind(args); err == nil {
secrets, total, err = b.Search(args.Name, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": secrets,
"total": total,
})
}
}
func secretFind(b biz.SecretBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
secret, raw, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, data.Map{"secret": secret, "raw": raw})
}
}
func secretDelete(b biz.SecretBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.ID, args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func secretSave(b biz.SecretBiz) web.HandlerFunc {
return func(ctx web.Context) error {
c := &biz.Secret{}
err := ctx.Bind(c, true)
if err == nil {
if c.ID == "" {
err = b.Create(c, ctx.User())
} else {
err = b.Update(c, ctx.User())
}
}
return ajax(ctx, err)
}
}

190
api/service.go Normal file
View File

@@ -0,0 +1,190 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// ServiceHandler encapsulates service related handlers.
type ServiceHandler struct {
Search web.HandlerFunc `path:"/search" auth:"service.view" desc:"search services"`
Find web.HandlerFunc `path:"/find" auth:"service.view" desc:"find service by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"service.delete" desc:"delete service"`
Restart web.HandlerFunc `path:"/restart" method:"post" auth:"service.restart" desc:"restart service"`
Rollback web.HandlerFunc `path:"/rollback" method:"post" auth:"service.rollback" desc:"rollback service"`
Scale web.HandlerFunc `path:"/scale" method:"post" auth:"service.edit" desc:"scale service"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"service.edit" desc:"create or update service"`
Deploy web.HandlerFunc `path:"/deploy" method:"post" auth:"service.deploy" desc:"deploy service"`
FetchLogs web.HandlerFunc `path:"/fetch-logs" auth:"service.logs" desc:"fetch logs of service"`
}
// NewService creates an instance of ServiceHandler
func NewService(b biz.ServiceBiz) *ServiceHandler {
return &ServiceHandler{
Search: serviceSearch(b),
Find: serviceFind(b),
Delete: serviceDelete(b),
Restart: serviceRestart(b),
Rollback: serviceRollback(b),
Scale: serviceScale(b),
Save: serviceSave(b),
Deploy: serviceDeploy(b),
FetchLogs: serviceFetchLogs(b),
}
}
func serviceSearch(b biz.ServiceBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
Mode string `json:"mode" bind:"mode"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
services []*biz.ServiceBase
total int
)
if err = ctx.Bind(args); err == nil {
services, total, err = b.Search(args.Name, args.Mode, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": services,
"total": total,
})
}
}
func serviceFind(b biz.ServiceBiz) web.HandlerFunc {
return func(ctx web.Context) error {
name := ctx.Query("name")
status := ctx.Query("status") == "true"
service, raw, err := b.Find(name, status)
if err != nil {
return err
}
return success(ctx, data.Map{"service": service, "raw": raw})
}
}
func serviceDelete(b biz.ServiceBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func serviceRestart(b biz.ServiceBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Restart(args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func serviceRollback(b biz.ServiceBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Rollback(args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func serviceScale(b biz.ServiceBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
Count uint64 `json:"count"`
Version uint64 `json:"version"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Scale(args.Name, args.Count, args.Version, ctx.User())
}
return ajax(ctx, err)
}
}
func serviceSave(b biz.ServiceBiz) web.HandlerFunc {
return func(ctx web.Context) error {
s := &biz.Service{}
err := ctx.Bind(s, true)
if err == nil {
if s.ID == "" {
err = b.Create(s, ctx.User())
} else {
err = b.Update(s, ctx.User())
}
}
return ajax(ctx, err)
}
}
func serviceDeploy(b biz.ServiceBiz) web.HandlerFunc {
return func(ctx web.Context) error {
service := &biz.Service{}
err := ctx.Bind(service, true)
if err != nil {
return err
}
var s *biz.Service
if s, _, err = b.Find(service.Name, false); err != nil {
return err
}
if s == nil {
err = b.Create(service, ctx.User())
} else {
err = b.Update(service, ctx.User())
}
return ajax(ctx, err)
}
}
func serviceFetchLogs(b biz.ServiceBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id" bind:"id"`
Lines int `json:"lines" bind:"lines"`
Timestamps bool `json:"timestamps" bind:"timestamps"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
stdout, stderr string
)
if err = ctx.Bind(args); err == nil {
stdout, stderr, err = b.FetchLogs(args.ID, args.Lines, args.Timestamps)
}
if err != nil {
return err
}
return success(ctx, data.Map{"stdout": stdout, "stderr": stderr})
}
}

57
api/setting.go Normal file
View File

@@ -0,0 +1,57 @@
package api
import (
"bytes"
"encoding/json"
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// SettingHandler encapsulates setting related handlers.
type SettingHandler struct {
Load web.HandlerFunc `path:"/load" auth:"setting.view" desc:"load setting"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"setting.edit" desc:"save setting"`
}
// NewSetting creates an instance of SettingHandler
func NewSetting(b biz.SettingBiz) *SettingHandler {
return &SettingHandler{
Load: settingLoad(b),
Save: settingSave(b),
}
}
func settingLoad(b biz.SettingBiz) web.HandlerFunc {
return func(ctx web.Context) error {
options, err := b.Load()
if err != nil {
return err
}
return success(ctx, options)
}
}
func settingSave(b biz.SettingBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Options json.RawMessage `json:"options"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
err = ctx.Bind(args)
if err != nil {
return
}
options := data.Map{}
d := json.NewDecoder(bytes.NewBuffer(args.Options))
d.UseNumber()
if err = d.Decode(&options); err == nil {
err = b.Save(args.ID, options, ctx.User())
}
return ajax(ctx, err)
}
}

142
api/stack.go Normal file
View File

@@ -0,0 +1,142 @@
package api
import (
"io"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
"github.com/cuigh/swirl/docker/compose"
)
// StackHandler encapsulates stack related handlers.
type StackHandler struct {
Search web.HandlerFunc `path:"/search" auth:"stack.view" desc:"search stacks"`
Find web.HandlerFunc `path:"/find" auth:"stack.view" desc:"find stack by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"stack.delete" desc:"delete stack"`
Shutdown web.HandlerFunc `path:"/shutdown" method:"post" auth:"stack.shutdown" desc:"shutdown stack"`
Deploy web.HandlerFunc `path:"/deploy" method:"post" auth:"stack.deploy" desc:"deploy stack"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"stack.edit" desc:"create or update stack"`
Upload web.HandlerFunc `path:"/upload" method:"post" auth:"*" desc:"upload compose file"`
}
// NewStack creates an instance of StackHandler
func NewStack(b biz.StackBiz) *StackHandler {
return &StackHandler{
Search: stackSearch(b),
Find: stackFind(b),
Delete: stackDelete(b),
Shutdown: stackShutdown(b),
Deploy: stackDeploy(b),
Save: stackSave(b),
Upload: stackUpload,
}
}
func stackUpload(ctx web.Context) (err error) {
file, _, err := ctx.File("content")
if err != nil {
return err
}
b, err := io.ReadAll(file)
if err != nil {
return err
}
return ctx.Data(b)
}
func stackSearch(b biz.StackBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
Filter string `json:"filter" bind:"filter"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
stacks []*biz.Stack
)
if err = ctx.Bind(args); err == nil {
stacks, err = b.Search(args.Name, args.Filter)
}
if err != nil {
return
}
return success(ctx, stacks)
}
}
func stackFind(b biz.StackBiz) web.HandlerFunc {
return func(ctx web.Context) error {
name := ctx.Query("name")
stack, err := b.Find(name)
if err != nil {
return err
}
return success(ctx, stack)
}
}
func stackDelete(b biz.StackBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func stackShutdown(b biz.StackBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Shutdown(args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func stackDeploy(b biz.StackBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Deploy(args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func stackSave(b biz.StackBiz) web.HandlerFunc {
return func(ctx web.Context) error {
stack := &biz.Stack{}
err := ctx.Bind(stack, true)
if err != nil {
return err
}
// Validate format
_, err = compose.Parse(stack.Name, stack.Content)
if err != nil {
return err
}
if stack.ID == "" {
err = b.Create(stack, ctx.User())
} else {
err = b.Update(stack, ctx.User())
}
return ajax(ctx, err)
}
}

85
api/system.go Normal file
View File

@@ -0,0 +1,85 @@
package api
import (
"context"
"runtime"
"github.com/cuigh/auxo/app"
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
"github.com/cuigh/swirl/docker"
)
//var ErrSystemInitialized = errors.New("system was already initialized")
// SystemHandler encapsulates system related handlers.
type SystemHandler struct {
CheckState web.HandlerFunc `path:"/check-state" auth:"*" desc:"check system state"`
CreateAdmin web.HandlerFunc `path:"/create-admin" method:"post" auth:"*" desc:"initialize administrator account"`
Version web.HandlerFunc `path:"/version" auth:"*" desc:"fetch app version"`
Summarize web.HandlerFunc `path:"/summarize" auth:"?" desc:"fetch statistics data"`
}
// NewSystem creates an instance of SystemHandler
func NewSystem(d *docker.Docker, b biz.SystemBiz) *SystemHandler {
return &SystemHandler{
CheckState: systemCheckState(b),
CreateAdmin: systemCreateAdmin(b),
Version: systemVersion,
Summarize: systemSummarize(d),
}
}
func systemCheckState(b biz.SystemBiz) web.HandlerFunc {
return func(c web.Context) (err error) {
state, err := b.CheckState()
if err != nil {
return err
}
return success(c, state)
}
}
func systemVersion(c web.Context) (err error) {
return success(c, data.Map{
"version": app.Version,
"goVersion": runtime.Version(),
})
}
func systemSummarize(d *docker.Docker) web.HandlerFunc {
return func(c web.Context) (err error) {
summary := struct {
NodeCount int `json:"nodeCount"`
NetworkCount int `json:"networkCount"`
ServiceCount int `json:"serviceCount"`
StackCount int `json:"stackCount"`
}{}
if summary.NodeCount, err = d.NodeCount(context.TODO()); err != nil {
return
}
if summary.NetworkCount, err = d.NetworkCount(context.TODO()); err != nil {
return
}
if summary.ServiceCount, err = d.ServiceCount(context.TODO()); err != nil {
return
}
if summary.StackCount, err = d.StackCount(context.TODO()); err != nil {
return
}
return success(c, summary)
}
}
func systemCreateAdmin(b biz.SystemBiz) web.HandlerFunc {
return func(c web.Context) (err error) {
user := &biz.User{}
if err = c.Bind(user, true); err == nil {
err = b.CreateAdmin(user)
}
return ajax(c, err)
}
}

86
api/task.go Normal file
View File

@@ -0,0 +1,86 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// TaskHandler encapsulates node related handlers.
type TaskHandler struct {
Search web.HandlerFunc `path:"/search" auth:"task.view" desc:"search tasks"`
Find web.HandlerFunc `path:"/find" auth:"task.view" desc:"find task by id"`
FetchLogs web.HandlerFunc `path:"/fetch-logs" auth:"task.logs" desc:"fetch logs of task"`
}
// NewTask creates an instance of TaskHandler
func NewTask(b biz.TaskBiz) *TaskHandler {
return &TaskHandler{
Search: taskSearch(b),
Find: taskFind(b),
FetchLogs: taskFetchLogs(b),
}
}
func taskSearch(b biz.TaskBiz) web.HandlerFunc {
type Args struct {
Service string `json:"service" bind:"service"`
State string `json:"state" bind:"state"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
tasks []*biz.Task
total int
)
if err = ctx.Bind(args); err == nil {
tasks, total, err = b.Search("", args.Service, args.State, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": tasks,
"total": total,
})
}
}
func taskFind(b biz.TaskBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
task, raw, err := b.Find(id)
if err != nil {
return err
}
return success(ctx, data.Map{"task": task, "raw": raw})
}
}
func taskFetchLogs(b biz.TaskBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id" bind:"id"`
Lines int `json:"lines" bind:"lines"`
Timestamps bool `json:"timestamps" bind:"timestamps"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
stdout, stderr string
)
if err = ctx.Bind(args); err == nil {
stdout, stderr, err = b.FetchLogs(args.ID, args.Lines, args.Timestamps)
}
if err != nil {
return err
}
return success(ctx, data.Map{"stdout": stdout, "stderr": stderr})
}
}

182
api/user.go Normal file
View File

@@ -0,0 +1,182 @@
package api
import (
"github.com/cuigh/auxo/app/container"
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
"github.com/cuigh/swirl/security"
)
// UserHandler encapsulates user related handlers.
type UserHandler struct {
SignIn web.HandlerFunc `path:"/sign-in" method:"post" auth:"*" desc:"user sign in"`
Search web.HandlerFunc `path:"/search" auth:"user.view" desc:"search users"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"user.edit" desc:"create or update user"`
Find web.HandlerFunc `path:"/find" auth:"user.view" desc:"find user by id"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"user.delete" desc:"delete user"`
SetStatus web.HandlerFunc `path:"/set-status" method:"post" auth:"user.edit" desc:"set user status"`
ModifyPassword web.HandlerFunc `path:"/modify-password" method:"post" auth:"?" desc:"modify password"`
ModifyProfile web.HandlerFunc `path:"/modify-profile" method:"post" auth:"?" desc:"modify profile"`
}
// NewUser creates an instance of UserHandler
func NewUser(b biz.UserBiz, eb biz.EventBiz, auth *security.Authenticator) *UserHandler {
return &UserHandler{
SignIn: userSignIn(auth, eb),
Search: userSearch(b),
Save: userSave(b),
Find: userFind(b),
Delete: userDelete(b),
SetStatus: userSetStatus(b),
ModifyPassword: userModifyPassword(b),
ModifyProfile: userModifyProfile(b),
}
}
func userSignIn(auth *security.Authenticator, eb biz.EventBiz) web.HandlerFunc {
type SignInArgs struct {
Name string `json:"name"`
Password string `json:"password"`
}
return func(ctx web.Context) (err error) {
var (
args = &SignInArgs{}
user web.User
token string
)
if err = ctx.Bind(args); err == nil {
if user, err = auth.Login(args.Name, args.Password); err == nil {
jwt := container.Find("identifier").(*security.JWT)
token, err = jwt.CreateToken(user.ID(), user.Name())
}
}
if err != nil {
return err
}
eb.CreateUser(biz.EventActionLogin, user.ID(), user.Name(), user)
return success(ctx, data.Map{
"token": token,
"id": user.ID(),
"name": user.Name(),
})
}
}
func userSave(b biz.UserBiz) web.HandlerFunc {
return func(ctx web.Context) error {
user := &biz.User{}
err := ctx.Bind(user, true)
if err == nil {
user.Type = biz.UserTypeInternal
if user.ID == "" {
_, err = b.Create(user, ctx.User())
} else {
err = b.Update(user, ctx.User())
}
}
return ajax(ctx, err)
}
}
func userSearch(b biz.UserBiz) web.HandlerFunc {
type Args struct {
Filter string `bind:"filter"` // admins, active, blocked
Name string `bind:"name"`
LoginName string `bind:"loginName"`
PageIndex int `bind:"pageIndex"`
PageSize int `bind:"pageSize"`
}
return func(ctx web.Context) error {
args := &Args{}
err := ctx.Bind(args)
if err != nil {
return err
}
users, total, err := b.Search(args.Name, args.LoginName, args.Filter, args.PageIndex, args.PageSize)
if err != nil {
return err
}
return success(ctx, data.Map{"items": users, "total": total})
}
}
func userFind(b biz.UserBiz) web.HandlerFunc {
return func(ctx web.Context) error {
id := ctx.Query("id")
if id == "" {
id = ctx.User().ID()
}
user, err := b.FindByID(id)
if err != nil {
return err
}
return success(ctx, user)
}
}
func userDelete(b biz.UserBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Name string `json:"name"`
}
return func(ctx web.Context) error {
args := &Args{}
err := ctx.Bind(args)
if err == nil {
err = b.Delete(args.ID, args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func userSetStatus(b biz.UserBiz) web.HandlerFunc {
type Args struct {
ID string `json:"id"`
Status int32 `json:"status"`
}
return func(ctx web.Context) error {
args := &Args{}
err := ctx.Bind(args)
if err == nil {
err = b.SetStatus(args.ID, args.Status)
}
return ajax(ctx, err)
}
}
func userModifyPassword(b biz.UserBiz) web.HandlerFunc {
type Args struct {
OldPassword string `json:"oldPwd"`
NewPassword string `json:"newPwd"`
}
return func(ctx web.Context) error {
args := &Args{}
err := ctx.Bind(args)
if err == nil {
err = b.ModifyPassword(ctx.User().ID(), args.OldPassword, args.NewPassword)
}
return ajax(ctx, err)
}
}
func userModifyProfile(b biz.UserBiz) web.HandlerFunc {
return func(ctx web.Context) error {
u := &biz.User{}
err := ctx.Bind(u, true)
if err == nil {
u.ID = ctx.User().ID()
err = b.ModifyProfile(u)
}
return ajax(ctx, err)
}
}

104
api/volume.go Normal file
View File

@@ -0,0 +1,104 @@
package api
import (
"github.com/cuigh/auxo/data"
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/swirl/biz"
)
// VolumeHandler encapsulates volume related handlers.
type VolumeHandler struct {
Search web.HandlerFunc `path:"/search" auth:"volume.view" desc:"search volumes"`
Find web.HandlerFunc `path:"/find" auth:"volume.view" desc:"find volume by name"`
Delete web.HandlerFunc `path:"/delete" method:"post" auth:"volume.delete" desc:"delete volume"`
Save web.HandlerFunc `path:"/save" method:"post" auth:"volume.edit" desc:"create or update volume"`
Prune web.HandlerFunc `path:"/prune" method:"post" auth:"volume.delete" desc:"delete unused volumes"`
}
// NewVolume creates an instance of VolumeHandler
func NewVolume(b biz.VolumeBiz) *VolumeHandler {
return &VolumeHandler{
Search: volumeSearch(b),
Find: volumeFind(b),
Delete: volumeDelete(b),
Save: volumeSave(b),
Prune: volumePrune(b),
}
}
func volumeSearch(b biz.VolumeBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name" bind:"name"`
PageIndex int `json:"pageIndex" bind:"pageIndex"`
PageSize int `json:"pageSize" bind:"pageSize"`
}
return func(ctx web.Context) (err error) {
var (
args = &Args{}
volumes []*biz.Volume
total int
)
if err = ctx.Bind(args); err == nil {
volumes, total, err = b.Search(args.Name, args.PageIndex, args.PageSize)
}
if err != nil {
return
}
return success(ctx, data.Map{
"items": volumes,
"total": total,
})
}
}
func volumeFind(b biz.VolumeBiz) web.HandlerFunc {
return func(ctx web.Context) error {
name := ctx.Query("name")
volume, raw, err := b.Find(name)
if err != nil {
return err
}
return success(ctx, data.Map{"volume": volume, "raw": raw})
}
}
func volumeDelete(b biz.VolumeBiz) web.HandlerFunc {
type Args struct {
Name string `json:"name"`
}
return func(ctx web.Context) (err error) {
args := &Args{}
if err = ctx.Bind(args); err == nil {
err = b.Delete(args.Name, ctx.User())
}
return ajax(ctx, err)
}
}
func volumeSave(b biz.VolumeBiz) web.HandlerFunc {
return func(ctx web.Context) error {
v := &biz.Volume{}
err := ctx.Bind(v, true)
if err == nil {
err = b.Create(v, ctx.User())
}
return ajax(ctx, err)
}
}
func volumePrune(b biz.VolumeBiz) web.HandlerFunc {
return func(ctx web.Context) error {
deletedVolumes, reclaimedSpace, err := b.Prune(ctx.User())
if err != nil {
return err
}
return success(ctx, data.Map{
"deletedVolumes": deletedVolumes,
"reclaimedSpace": reclaimedSpace,
})
}
}