diff --git a/biz/docker/config.go b/biz/docker/config.go
index 6bf0b39..74549c8 100644
--- a/biz/docker/config.go
+++ b/biz/docker/config.go
@@ -5,6 +5,7 @@ import (
"sort"
"github.com/cuigh/swirl/misc"
+ "github.com/cuigh/swirl/model"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm"
@@ -34,18 +35,47 @@ func ConfigList(name string, pageIndex, pageSize int) (configs []swarm.Config, t
}
// ConfigCreate create a config.
-func ConfigCreate(name string, data []byte, labels map[string]string) error {
+func ConfigCreate(info *model.ConfigCreateInfo) error {
return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
- // todo:
spec := swarm.ConfigSpec{}
- spec.Name = name
- spec.Data = data
- spec.Labels = labels
+ spec.Name = info.Name
+ spec.Data = []byte(info.Data)
+ spec.Labels = info.Labels.ToMap()
_, err = cli.ConfigCreate(ctx, spec)
return
})
}
+// ConfigUpdate update a config.
+func ConfigUpdate(info *model.ConfigUpdateInfo) error {
+ return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
+ var cfg swarm.Config
+ cfg, _, err = cli.ConfigInspectWithRaw(ctx, info.ID)
+ if err != nil {
+ return err
+ }
+
+ spec := cfg.Spec
+ // only the Labels field can be updated on API 1.30
+ //spec.Name = info.Name
+ //spec.Data = []byte(info.Data)
+ spec.Labels = info.Labels.ToMap()
+ return cli.ConfigUpdate(ctx, info.ID, cfg.Version, spec)
+ })
+}
+
+// ConfigInspect returns config information with raw data.
+func ConfigInspect(id string) (cfg swarm.Config, raw []byte, err error) {
+ var (
+ ctx context.Context
+ cli *client.Client
+ )
+ if ctx, cli, err = mgr.Client(); err == nil {
+ cfg, raw, err = cli.ConfigInspectWithRaw(ctx, id)
+ }
+ return
+}
+
// ConfigRemove remove a config.
func ConfigRemove(ids []string) error {
return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
diff --git a/biz/docker/secret.go b/biz/docker/secret.go
index 9022230..9ff85ae 100644
--- a/biz/docker/secret.go
+++ b/biz/docker/secret.go
@@ -4,11 +4,12 @@ import (
"context"
"sort"
+ "github.com/cuigh/swirl/misc"
+ "github.com/cuigh/swirl/model"
"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/api/types/swarm"
"github.com/docker/docker/client"
- "github.com/cuigh/swirl/misc"
)
// SecretList return all secrets.
@@ -34,18 +35,47 @@ func SecretList(name string, pageIndex, pageSize int) (secrets []swarm.Secret, t
}
// SecretCreate create a secret.
-func SecretCreate(name string, data []byte, labels map[string]string) error {
+func SecretCreate(info *model.ConfigCreateInfo) error {
return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
- // todo:
spec := swarm.SecretSpec{}
- spec.Name = name
- spec.Data = data
- spec.Labels = labels
+ spec.Name = info.Name
+ spec.Data = []byte(info.Data)
+ spec.Labels = info.Labels.ToMap()
_, err = cli.SecretCreate(ctx, spec)
return
})
}
+// SecretUpdate update a config.
+func SecretUpdate(info *model.ConfigUpdateInfo) error {
+ return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
+ var secret swarm.Secret
+ secret, _, err = cli.SecretInspectWithRaw(ctx, info.ID)
+ if err != nil {
+ return err
+ }
+
+ spec := secret.Spec
+ // only the Labels field can be updated on API 1.30
+ //spec.Name = info.Name
+ //spec.Data = []byte(info.Data)
+ spec.Labels = info.Labels.ToMap()
+ return cli.SecretUpdate(ctx, info.ID, secret.Version, spec)
+ })
+}
+
+// SecretInspect returns secret information with raw data.
+func SecretInspect(id string) (secret swarm.Secret, raw []byte, err error) {
+ var (
+ ctx context.Context
+ cli *client.Client
+ )
+ if ctx, cli, err = mgr.Client(); err == nil {
+ secret, raw, err = cli.SecretInspectWithRaw(ctx, id)
+ }
+ return
+}
+
// SecretRemove remove a secret.
func SecretRemove(id string) error {
return mgr.Do(func(ctx context.Context, cli *client.Client) (err error) {
diff --git a/controller/config.go b/controller/config.go
index e7ca659..26e4bb3 100644
--- a/controller/config.go
+++ b/controller/config.go
@@ -5,6 +5,7 @@ import (
"github.com/cuigh/auxo/net/web"
"github.com/cuigh/auxo/util/cast"
+ "github.com/cuigh/swirl/biz"
"github.com/cuigh/swirl/biz/docker"
"github.com/cuigh/swirl/model"
)
@@ -14,6 +15,8 @@ type ConfigController struct {
Delete web.HandlerFunc `path:"/delete" method:"post" name:"config.delete" authorize:"!" desc:"delete config"`
New web.HandlerFunc `path:"/new" name:"config.new" authorize:"!" desc:"new config page"`
Create web.HandlerFunc `path:"/new" method:"post" name:"config.create" authorize:"!" desc:"create config"`
+ Edit web.HandlerFunc `path:"/:id/edit" name:"config.edit" authorize:"!" desc:"edit config page"`
+ Update web.HandlerFunc `path:"/:id/update" method:"post" name:"config.update" authorize:"!" desc:"update config"`
}
func Config() (c *ConfigController) {
@@ -45,23 +48,35 @@ func Config() (c *ConfigController) {
}
c.Create = func(ctx web.Context) error {
- v := struct {
- Name string `json:"name"`
- Data string `json:"data"`
- Labels []struct {
- Name string `json:"name"`
- Value string `json:"value"`
- } `json:"labels"`
- }{}
- err := ctx.Bind(&v)
+ v := &model.ConfigCreateInfo{}
+ err := ctx.Bind(v)
if err == nil {
- labels := make(map[string]string)
- for _, l := range v.Labels {
- if l.Name != "" && l.Value != "" {
- labels[l.Name] = l.Value
- }
+ err = docker.ConfigCreate(v)
+ if err == nil {
+ biz.Event.CreateConfig(model.EventActionCreate, v.Name, ctx.User())
+ }
+ }
+ return ajaxResult(ctx, err)
+ }
+
+ c.Edit = func(ctx web.Context) error {
+ id := ctx.P("id")
+ cfg, _, err := docker.ConfigInspect(id)
+ if err != nil {
+ return err
+ }
+ m := newModel(ctx).Add("Config", cfg)
+ return ctx.Render("config/edit", m)
+ }
+
+ c.Update = func(ctx web.Context) error {
+ v := &model.ConfigUpdateInfo{}
+ err := ctx.Bind(v)
+ if err == nil {
+ err = docker.ConfigUpdate(v)
+ if err == nil {
+ biz.Event.CreateConfig(model.EventActionUpdate, v.Name, ctx.User())
}
- err = docker.ConfigCreate(v.Name, []byte(v.Data), labels)
}
return ajaxResult(ctx, err)
}
diff --git a/controller/secret.go b/controller/secret.go
index b6120d4..1d5f225 100644
--- a/controller/secret.go
+++ b/controller/secret.go
@@ -15,6 +15,8 @@ type SecretController struct {
Delete web.HandlerFunc `path:"/delete" method:"post" name:"secret.delete" authorize:"!" desc:"delete secret"`
New web.HandlerFunc `path:"/new" name:"secret.new" authorize:"!" desc:"new secret page"`
Create web.HandlerFunc `path:"/new" method:"post" name:"secret.create" authorize:"!" desc:"create secret"`
+ Edit web.HandlerFunc `path:"/:id/edit" name:"secret.edit" authorize:"!" desc:"edit secret page"`
+ Update web.HandlerFunc `path:"/:id/update" method:"post" name:"secret.update" authorize:"!" desc:"update secret"`
}
func Secret() (c *SecretController) {
@@ -54,23 +56,10 @@ func Secret() (c *SecretController) {
}
c.Create = func(ctx web.Context) error {
- v := struct {
- Name string `json:"name"`
- Data string `json:"data"`
- Labels []struct {
- Name string `json:"name"`
- Value string `json:"value"`
- } `json:"labels"`
- }{}
- err := ctx.Bind(&v)
+ v := &model.ConfigCreateInfo{}
+ err := ctx.Bind(v)
if err == nil {
- labels := make(map[string]string)
- for _, l := range v.Labels {
- if l.Name != "" && l.Value != "" {
- labels[l.Name] = l.Value
- }
- }
- err = docker.SecretCreate(v.Name, []byte(v.Data), labels)
+ err = docker.SecretCreate(v)
if err == nil {
biz.Event.CreateSecret(model.EventActionCreate, v.Name, ctx.User())
}
@@ -78,5 +67,27 @@ func Secret() (c *SecretController) {
return ajaxResult(ctx, err)
}
+ c.Edit = func(ctx web.Context) error {
+ id := ctx.P("id")
+ secret, _, err := docker.SecretInspect(id)
+ if err != nil {
+ return err
+ }
+ m := newModel(ctx).Add("Secret", secret)
+ return ctx.Render("secret/edit", m)
+ }
+
+ c.Update = func(ctx web.Context) error {
+ v := &model.ConfigUpdateInfo{}
+ err := ctx.Bind(v)
+ if err == nil {
+ err = docker.SecretUpdate(v)
+ if err == nil {
+ biz.Event.CreateSecret(model.EventActionUpdate, v.Name, ctx.User())
+ }
+ }
+ return ajaxResult(ctx, err)
+ }
+
return
}
diff --git a/misc/perm.go b/misc/perm.go
index 89c044d..9ec14e7 100644
--- a/misc/perm.go
+++ b/misc/perm.go
@@ -104,8 +104,10 @@ var Perms = []PermGroup{
Perms: []Perm{
{Key: "secret.list", Text: "View list"},
{Key: "secret.new", Text: "View new"},
+ {Key: "secret.edit", Text: "View edit"},
{Key: "secret.create", Text: "Create"},
{Key: "secret.delete", Text: "Delete"},
+ {Key: "secret.update", Text: "Update"},
},
},
{
@@ -113,8 +115,10 @@ var Perms = []PermGroup{
Perms: []Perm{
{Key: "config.list", Text: "View list"},
{Key: "config.new", Text: "View new"},
+ {Key: "config.edit", Text: "View edit"},
{Key: "config.create", Text: "Create"},
{Key: "config.delete", Text: "Delete"},
+ {Key: "config.update", Text: "Update"},
},
},
{
diff --git a/model/docker.go b/model/docker.go
index 3640bf6..2325445 100644
--- a/model/docker.go
+++ b/model/docker.go
@@ -3,11 +3,11 @@ package model
import (
"encoding/base64"
"encoding/json"
+ "fmt"
+ "os"
+ "strconv"
"strings"
"time"
- "fmt"
- "strconv"
- "os"
"github.com/cuigh/auxo/data/size"
"github.com/docker/docker/api/types"
@@ -466,6 +466,17 @@ func (pc *PlacementConstraint) ToConstraint() string {
return ""
}
+type ConfigCreateInfo struct {
+ Name string `json:"name"`
+ Data string `json:"data"`
+ Labels Options `json:"labels"`
+}
+
+type ConfigUpdateInfo struct {
+ ID string `json:"id"`
+ ConfigCreateInfo
+}
+
type TaskInfo struct {
swarm.Task
NodeName string
diff --git a/views/config/edit.jet b/views/config/edit.jet
new file mode 100644
index 0000000..21fb244
--- /dev/null
+++ b/views/config/edit.jet
@@ -0,0 +1,76 @@
+{{ extends "../_layouts/default" }}
+{{ import "../_modules/form" }}
+
+{{ block script() }}
+
+{{ end }}
+
+{{ block body() }}
+
+ CONFIG
+
+
+ Configs are non-sensitive information that can be used by services, such as configuration files.
+
+