Add ‘Template’ option to configs and secrets

This commit is contained in:
cuigh 2018-04-24 12:16:42 +08:00
parent 4266fcd296
commit 6e5a27b66d
11 changed files with 118 additions and 102 deletions

View File

@ -41,6 +41,12 @@ func ConfigCreate(info *model.ConfigCreateInfo) error {
spec.Name = info.Name spec.Name = info.Name
spec.Data = []byte(info.Data) spec.Data = []byte(info.Data)
spec.Labels = info.Labels.ToMap() spec.Labels = info.Labels.ToMap()
if info.Template.Name != "" {
spec.Templating = &swarm.Driver{
Name: info.Template.Name,
Options: info.Template.Options,
}
}
_, err = cli.ConfigCreate(ctx, spec) _, err = cli.ConfigCreate(ctx, spec)
return return
}) })

View File

@ -12,7 +12,7 @@ import (
) )
const ( const (
apiVersion = "1.32" defaultAPIVersion = "1.32"
) )
var mgr = &manager{} var mgr = &manager{}
@ -37,11 +37,15 @@ func (m *manager) Client() (ctx context.Context, cli *client.Client, err error)
defer m.locker.Unlock() defer m.locker.Unlock()
if m.client == nil { if m.client == nil {
apiVersion := misc.Options.DockerAPIVersion
if apiVersion == "" {
apiVersion = defaultAPIVersion
}
if misc.Options.DockerEndpoint == "" { if misc.Options.DockerEndpoint == "" {
os.Setenv("DOCKER_API_VERSION", apiVersion) os.Setenv("DOCKER_API_VERSION", apiVersion)
m.client, err = client.NewEnvClient() m.client, err = client.NewClientWithOpts(client.FromEnv)
} else { } else {
m.client, err = client.NewClient(misc.Options.DockerEndpoint, apiVersion, nil, nil) m.client, err = client.NewClientWithOpts(client.WithHost(misc.Options.DockerEndpoint), client.WithVersion(apiVersion))
} }
if err != nil { if err != nil {
return return

View File

@ -41,6 +41,12 @@ func SecretCreate(info *model.ConfigCreateInfo) error {
spec.Name = info.Name spec.Name = info.Name
spec.Data = []byte(info.Data) spec.Data = []byte(info.Data)
spec.Labels = info.Labels.ToMap() spec.Labels = info.Labels.ToMap()
if info.Template.Name != "" {
spec.Templating = &swarm.Driver{
Name: info.Template.Name,
Options: info.Template.Options,
}
}
_, err = cli.SecretCreate(ctx, spec) _, err = cli.SecretCreate(ctx, spec)
return return
}) })

View File

@ -34,6 +34,7 @@ field.login-name: Login name
field.password: Password field.password: Password
field.id: ID field.id: ID
field.tag: Tags field.tag: Tags
field.label: Labels
field.size: Size field.size: Size
field.created-at: Created at field.created-at: Created at
field.created-by: Created by field.created-by: Created by
@ -57,6 +58,8 @@ field.title: Title
field.legend: Legend field.legend: Legend
field.desc: Description field.desc: Description
field.dashboard: Dashboard field.dashboard: Dashboard
field.data: Data
field.template: Template
# menu # menu
menu.home: Home menu.home: Home

View File

@ -34,6 +34,7 @@ field.login-name: 登录名称
field.password: 密码 field.password: 密码
field.id: ID field.id: ID
field.tag: 标签 field.tag: 标签
field.label: 标签
field.size: 大小 field.size: 大小
field.created-at: 创建时间 field.created-at: 创建时间
field.created-by: 创建人 field.created-by: 创建人
@ -57,6 +58,8 @@ field.title: 标题
field.legend: 图例 field.legend: 图例
field.desc: 描述 field.desc: 描述
field.dashboard: 仪表盘 field.dashboard: 仪表盘
field.data: 数据
field.template: 模板
# menu # menu
menu.home: 首页 menu.home: 首页

View File

@ -7,14 +7,16 @@ import (
) )
const ( const (
keyDockerEndpoint = "swirl.docker_endpoint" keyDockerEndpoint = "swirl.docker_endpoint"
keyDBType = "swirl.db_type" keyDockerAPIVersion = "swirl.docker_api_version"
keyDBAddress = "swirl.db_address" keyDBType = "swirl.db_type"
keyAuthTimeout = "swirl.auth_timeout" keyDBAddress = "swirl.db_address"
envDockerEndpoint = "DOCKER_ENDPOINT" keyAuthTimeout = "swirl.auth_timeout"
envDBType = "DB_TYPE" envDockerEndpoint = "DOCKER_ENDPOINT"
envDBAddress = "DB_ADDRESS" envDockerAPIVersion = "DOCKER_API_VERSION"
envAuthTimeout = "AUTH_TIMEOUT" envDBType = "DB_TYPE"
envDBAddress = "DB_ADDRESS"
envAuthTimeout = "AUTH_TIMEOUT"
) )
// TimeZones holds some commonly used time-zones. // TimeZones holds some commonly used time-zones.
@ -51,10 +53,11 @@ var TimeZones = []struct {
// Options holds custom options of swirl. // Options holds custom options of swirl.
var Options = &struct { var Options = &struct {
DockerEndpoint string DockerEndpoint string
DBType string DockerAPIVersion string
DBAddress string DBType string
AuthTimeout time.Duration DBAddress string
AuthTimeout time.Duration
}{ }{
DBType: "mongo", DBType: "mongo",
DBAddress: "localhost:27017/swirl", DBAddress: "localhost:27017/swirl",
@ -64,6 +67,7 @@ var Options = &struct {
// BindOptions binds options to environment variables. // BindOptions binds options to environment variables.
func BindOptions() { func BindOptions() {
config.BindEnv(keyDockerEndpoint, envDockerEndpoint) config.BindEnv(keyDockerEndpoint, envDockerEndpoint)
config.BindEnv(keyDockerAPIVersion, envDockerAPIVersion)
config.BindEnv(keyDBType, envDBType) config.BindEnv(keyDBType, envDBType)
config.BindEnv(keyDBAddress, envDBAddress) config.BindEnv(keyDBAddress, envDBAddress)
config.BindEnv(keyAuthTimeout, envAuthTimeout) config.BindEnv(keyAuthTimeout, envAuthTimeout)

View File

@ -553,10 +553,16 @@ func (pc *PlacementConstraint) ToConstraint() string {
return "" return ""
} }
type Driver struct {
Name string `json:"name,omitempty"`
Options map[string]string `json:"options,omitempty"`
}
type ConfigCreateInfo struct { type ConfigCreateInfo struct {
Name string `json:"name"` Name string `json:"name"`
Data string `json:"data"` Data string `json:"data"`
Labels Options `json:"labels"` Labels Options `json:"labels"`
Template Driver `json:"template"`
} }
type ConfigUpdateInfo struct { type ConfigUpdateInfo struct {

View File

@ -50,16 +50,29 @@
<input name="id" value="{{ .Config.ID }}" type="hidden"> <input name="id" value="{{ .Config.ID }}" type="hidden">
<input name="version" value="{{ .Config.Version.Index }}" data-type="integer" type="hidden"> <input name="version" value="{{ .Config.Version.Index }}" data-type="integer" type="hidden">
<div class="field"> <div class="field">
<label class="label">Data</label> <label class="label">{{ i18n("field.data") }}</label>
<div class="control"> <div class="control">
<textarea class="textarea" rows="12" readonly>{{ .Config.Spec.Data }}</textarea> <textarea class="textarea" rows="12" readonly>{{ .Config.Spec.Data }}</textarea>
</div> </div>
<p class="help is-danger">Editing is not supported now!</p> <p class="help">Editing is not supported now!</p>
</div> </div>
<div class="field"> <div class="field">
<label class="label">Labels</label> <label class="label">{{ i18n("field.label") }}</label>
{{ yield options(name="label", items=.Config.Spec.Labels) }} {{ yield options(name="label", items=.Config.Spec.Labels) }}
</div> </div>
<div class="field">
<label class="label">{{ i18n("field.template") }}</label>
<div class="control">
{{ if .Config.Spec.Templating }}
{{ yield radio(name="template.name", value="", label="None", disabled=true, checked=.Config.Spec.Templating.Name) }}
{{ yield radio(name="template.name", value="golang", label="Golang", disabled=true, checked=.Config.Spec.Templating.Name) }}
{{ else }}
{{ yield radio(name="template.name", value="", label="None", disabled=true, checked="") }}
{{ yield radio(name="template.name", value="golang", label="Golang", disabled=true) }}
{{ end }}
</div>
<p class="help">Template feature needs Docker API version 1.37+</p>
</div>
{{ yield form_submit(url="/config/") }} {{ yield form_submit(url="/config/") }}
</form> </form>
</div> </div>

View File

@ -19,52 +19,31 @@
<h2 class="title">Create config</h2> <h2 class="title">Create config</h2>
<hr> <hr>
<form method="post" data-form="ajax-json" data-url="/config/"> <form method="post" data-form="ajax-json" data-url="/config/">
<div class="field is-horizontal"> <div class="field">
<div class="field-label is-normal"> <label class="label">{{ i18n("field.name") }}</label>
<label class="label">{{ i18n("field.name") }}</label> <div class="control">
</div> <input name="name" class="input" type="text" placeholder="Config file name" data-v-rule="native" required>
<div class="field-body">
<div class="field">
<p class="control is-expanded">
<input name="name" class="input" type="text" placeholder="Config file name" data-v-rule="native" required>
</p>
</div>
</div> </div>
</div> </div>
<div class="field is-horizontal"> <div class="field">
<div class="field-label is-normal"> <label class="label">{{ i18n("field.data") }}</label>
<label class="label">Data</label> <div class="control">
</div> <textarea name="data" class="textarea" rows="12" placeholder="Config file content" data-v-rule="native" required></textarea>
<div class="field-body">
<div class="field">
<div class="control">
<textarea name="data" class="textarea" rows="12" placeholder="Config file content" data-v-rule="native" required></textarea>
</div>
</div>
</div> </div>
</div> </div>
<div class="field is-horizontal"> <div class="field">
<div class="field-label is-normal"> <label class="label">{{ i18n("field.label") }}</label>
<label class="label">Labels</label> {{ yield options(name="label") }}
</div>
<div class="field-body">
<div class="field">
{{ yield options(name="label") }}
</div>
</div>
</div> </div>
<div class="field is-horizontal"> <div class="field">
<div class="field-label"> <label class="label">{{ i18n("field.template") }}</label>
</div> <div class="control">
<div class="field-body"> {{ yield radio(name="template.name", value="", label="None", checked="") }}
<div class="field"> {{ yield radio(name="template.name", value="golang", label="Golang") }}
<div class="control">
<button type="submit" class="button is-primary">{{ i18n("button.submit") }}</button>
<a href="/config/" class="button is-link">{{ i18n("button.cancel") }}</a>
</div>
</div>
</div> </div>
<p class="help">Template feature needs Docker API version 1.37+</p>
</div> </div>
{{ yield form_submit(url="/config/") }}
</form> </form>
</section> </section>
{{ end }} {{ end }}

View File

@ -50,16 +50,29 @@
<input name="id" value="{{ .Secret.ID }}" type="hidden"> <input name="id" value="{{ .Secret.ID }}" type="hidden">
<input name="version" value="{{ .Secret.Version.Index }}" data-type="integer" type="hidden"> <input name="version" value="{{ .Secret.Version.Index }}" data-type="integer" type="hidden">
{*<div class="field">*} {*<div class="field">*}
{*<label class="label">Data</label>*} {*<label class="label">{{ i18n("field.data") }}</label>*}
{*<div class="control">*} {*<div class="control">*}
{*<textarea class="textarea" rows="12" readonly>{{ .Secret.Spec.Data }}</textarea>*} {*<textarea class="textarea" rows="12" readonly>{{ .Secret.Spec.Data }}</textarea>*}
{*</div>*} {*</div>*}
{*<p class="help is-danger">Editing is not supported now!</p>*} {*<p class="help">Editing is not supported now!</p>*}
{*</div>*} {*</div>*}
<div class="field"> <div class="field">
<label class="label">Labels</label> <label class="label">{{ i18n("field.label") }}</label>
{{ yield options(name="label", items=.Secret.Spec.Labels) }} {{ yield options(name="label", items=.Secret.Spec.Labels) }}
</div> </div>
<div class="field">
<label class="label">{{ i18n("field.template") }}</label>
<div class="control">
{{ if .Secret.Spec.Templating }}
{{ yield radio(name="template.name", value="", label="None", disabled=true, checked=.Secret.Spec.Templating.Name) }}
{{ yield radio(name="template.name", value="golang", label="Golang", disabled=true, checked=.Secret.Spec.Templating.Name) }}
{{ else }}
{{ yield radio(name="template.name", value="", label="None", disabled=true, checked="") }}
{{ yield radio(name="template.name", value="golang", label="Golang", disabled=true) }}
{{ end }}
</div>
<p class="help">Template feature needs Docker API version 1.37+</p>
</div>
{{ yield form_submit(url="/secret/") }} {{ yield form_submit(url="/secret/") }}
</form> </form>
</div> </div>

View File

@ -19,52 +19,31 @@
<h2 class="title">Create secret</h2> <h2 class="title">Create secret</h2>
<hr> <hr>
<form method="post" data-form="ajax-json" data-url="/secret/"> <form method="post" data-form="ajax-json" data-url="/secret/">
<div class="field is-horizontal"> <div class="field">
<div class="field-label is-normal"> <label class="label">{{ i18n("field.name") }}</label>
<label class="label">{{ i18n("field.name") }}</label> <div class="control">
</div> <input name="name" class="input" type="text" placeholder="Secret file name" data-v-rule="native" required>
<div class="field-body">
<div class="field">
<p class="control is-expanded">
<input name="name" class="input" type="text" placeholder="Secret file name" data-v-rule="native" required>
</p>
</div>
</div> </div>
</div> </div>
<div class="field is-horizontal"> <div class="field">
<div class="field-label is-normal"> <label class="label">{{ i18n("field.data") }}</label>
<label class="label">Data</label> <div class="control">
</div> <textarea name="data" class="textarea" rows="12" placeholder="Secret file content" data-v-rule="native" required></textarea>
<div class="field-body">
<div class="field">
<div class="control">
<textarea name="data" class="textarea" rows="12" placeholder="Secret file content" data-v-rule="native" required></textarea>
</div>
</div>
</div> </div>
</div> </div>
<div class="field is-horizontal"> <div class="field">
<div class="field-label is-normal"> <label class="label">{{ i18n("field.label") }}</label>
<label class="label">Labels</label> {{ yield options(name="label") }}
</div>
<div class="field-body">
<div class="field">
{{ yield options(name="label") }}
</div>
</div>
</div> </div>
<div class="field is-horizontal"> <div class="field">
<div class="field-label"> <label class="label">{{ i18n("field.template") }}</label>
</div> <div class="control">
<div class="field-body"> {{ yield radio(name="template.name", value="", label="None", checked="") }}
<div class="field"> {{ yield radio(name="template.name", value="golang", label="Golang") }}
<div class="control">
<button type="submit" class="button is-primary">{{ i18n("button.submit") }}</button>
<a href="/secret/" class="button is-link">{{ i18n("button.cancel") }}</a>
</div>
</div>
</div> </div>
<p class="help">Template feature needs Docker API version 1.37+</p>
</div> </div>
{{ yield form_submit(url="/secret/") }}
</form> </form>
</section> </section>
{{ end }} {{ end }}