host download tokens
This commit is contained in:
parent
1e3ac9a0fb
commit
bde41c9859
@ -301,8 +301,11 @@ func (ctx *renderContext) templateFuncs(ctxMap map[string]interface{}) map[strin
|
||||
},
|
||||
|
||||
"ssh_host_keys": func(dir string) (s string) {
|
||||
return fmt.Sprintf("{{ ssh_host_keys %q %q %q}}",
|
||||
dir, cluster, ctx.Host.Name)
|
||||
return fmt.Sprintf("{{ ssh_host_keys %q %q \"\"}}",
|
||||
dir, cluster)
|
||||
},
|
||||
"host_download_token": func() (s string) {
|
||||
return "{{ host_download_token }}"
|
||||
},
|
||||
|
||||
"hosts_of_group": func() (hosts []interface{}) {
|
||||
|
@ -133,33 +133,6 @@ func templateFuncs(sslCfg *cfsslconfig.Config) map[string]any {
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
"ssh_host_keys": func(dir, cluster, host string) (s string, err error) {
|
||||
pairs, err := getSSHKeyPairs(host)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
files := make([]config.FileDef, 0, len(pairs)*2)
|
||||
|
||||
for _, pair := range pairs {
|
||||
basePath := path.Join(dir, "ssh_host_"+pair.Type+"_key")
|
||||
files = append(files, []config.FileDef{
|
||||
{
|
||||
Path: basePath,
|
||||
Mode: 0600,
|
||||
Content: pair.Private,
|
||||
},
|
||||
{
|
||||
Path: basePath + ".pub",
|
||||
Mode: 0644,
|
||||
Content: pair.Public,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
return asYaml(files)
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
3
cmd/dkl-local-server/host-download-tokens.go
Normal file
3
cmd/dkl-local-server/host-download-tokens.go
Normal file
@ -0,0 +1,3 @@
|
||||
package main
|
||||
|
||||
var hostDownloadTokens = KVSecrets[string]{"hosts/download-tokens"}
|
@ -4,10 +4,12 @@ import (
|
||||
"bytes"
|
||||
"crypto/sha256"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path"
|
||||
"path/filepath"
|
||||
"text/template"
|
||||
|
||||
@ -115,7 +117,7 @@ func (ctx *renderContext) BootstrapConfig() (ba []byte, cfg *bsconfig.Config, er
|
||||
|
||||
func (ctx *renderContext) render(templateText string) (ba []byte, err error) {
|
||||
tmpl, err := template.New(ctx.Host.Name + "/config").
|
||||
Funcs(templateFuncs(ctx.SSLConfig)).
|
||||
Funcs(ctx.TemplateFuncs()).
|
||||
Parse(templateText)
|
||||
|
||||
if err != nil {
|
||||
@ -168,3 +170,69 @@ func asMap(v interface{}) map[string]interface{} {
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func (ctx *renderContext) TemplateFuncs() map[string]any {
|
||||
funcs := templateFuncs(ctx.SSLConfig)
|
||||
|
||||
for name, method := range map[string]any{
|
||||
"ssh_host_keys": func(dir, cluster, host string) (s string, err error) {
|
||||
if host == "" {
|
||||
host = ctx.Host.Name
|
||||
}
|
||||
if host != ctx.Host.Name {
|
||||
err = fmt.Errorf("wrong host name")
|
||||
return
|
||||
}
|
||||
|
||||
pairs, err := getSSHKeyPairs(host)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
files := make([]config.FileDef, 0, len(pairs)*2)
|
||||
|
||||
for _, pair := range pairs {
|
||||
basePath := path.Join(dir, "ssh_host_"+pair.Type+"_key")
|
||||
files = append(files, []config.FileDef{
|
||||
{
|
||||
Path: basePath,
|
||||
Mode: 0600,
|
||||
Content: pair.Private,
|
||||
},
|
||||
{
|
||||
Path: basePath + ".pub",
|
||||
Mode: 0644,
|
||||
Content: pair.Public,
|
||||
},
|
||||
}...)
|
||||
}
|
||||
|
||||
return asYaml(files)
|
||||
},
|
||||
"host_download_token": func() (token string, err error) {
|
||||
key := ctx.Host.Name
|
||||
token, found, err := hostDownloadTokens.Get(key)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
if !found {
|
||||
token, err = newToken(32)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
err = hostDownloadTokens.Put(key, token)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
} {
|
||||
funcs[name] = method
|
||||
}
|
||||
|
||||
return funcs
|
||||
}
|
||||
|
@ -18,7 +18,7 @@ var trustXFF = flag.Bool("trust-xff", true, "Trust the X-Forwarded-For header")
|
||||
type wsHost struct {
|
||||
prefix string
|
||||
hostDoc string
|
||||
getHost func(req *restful.Request) string
|
||||
getHost func(req *restful.Request) (hostName string, err error)
|
||||
}
|
||||
|
||||
func (ws *wsHost) register(rws *restful.WebService, alterRB func(*restful.RouteBuilder)) {
|
||||
@ -105,13 +105,17 @@ func (ws *wsHost) register(rws *restful.WebService, alterRB func(*restful.RouteB
|
||||
}
|
||||
|
||||
func (ws *wsHost) host(req *restful.Request, resp *restful.Response) (host *localconfig.Host, cfg *localconfig.Config) {
|
||||
hostname := ws.getHost(req)
|
||||
hostname, err := ws.getHost(req)
|
||||
if err != nil {
|
||||
wsError(resp, err)
|
||||
return
|
||||
}
|
||||
if hostname == "" {
|
||||
wsNotFound(req, resp)
|
||||
return
|
||||
}
|
||||
|
||||
cfg, err := readConfig()
|
||||
cfg, err = readConfig()
|
||||
if err != nil {
|
||||
wsError(resp, err)
|
||||
return
|
||||
|
@ -120,8 +120,8 @@ func registerWS(rest *restful.Container) {
|
||||
(&wsHost{
|
||||
prefix: "/hosts/{host-name}",
|
||||
hostDoc: "given host",
|
||||
getHost: func(req *restful.Request) string {
|
||||
return req.PathParameter("host-name")
|
||||
getHost: func(req *restful.Request) (string, error) {
|
||||
return req.PathParameter("host-name"), nil
|
||||
},
|
||||
}).register(ws, func(rb *restful.RouteBuilder) {
|
||||
})
|
||||
@ -146,10 +146,37 @@ func registerWS(rest *restful.Container) {
|
||||
rb.Notes("In this case, the host is detected from the remote IP")
|
||||
})
|
||||
|
||||
// Hosts by token API
|
||||
ws = &restful.WebService{}
|
||||
ws.Path("/hosts-by-token/{host-token}")
|
||||
|
||||
(&wsHost{
|
||||
hostDoc: "token's host",
|
||||
getHost: func(req *restful.Request) (host string, err error) {
|
||||
reqToken := req.PathParameter("host-name")
|
||||
|
||||
data, err := hostDownloadTokens.Data()
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
for h, token := range data {
|
||||
if token == reqToken {
|
||||
host = h
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
},
|
||||
}).register(ws, func(rb *restful.RouteBuilder) {
|
||||
rb.Notes("In this case, the host is detected from the remote IP")
|
||||
})
|
||||
|
||||
rest.Add(ws)
|
||||
}
|
||||
|
||||
func detectHost(req *restful.Request) string {
|
||||
func detectHost(req *restful.Request) (hostName string, err error) {
|
||||
r := req.Request
|
||||
remoteAddr := r.RemoteAddr
|
||||
|
||||
@ -167,17 +194,17 @@ func detectHost(req *restful.Request) string {
|
||||
|
||||
cfg, err := readConfig()
|
||||
if err != nil {
|
||||
return ""
|
||||
return
|
||||
}
|
||||
|
||||
host := cfg.HostByIP(hostIP)
|
||||
|
||||
if host == nil {
|
||||
log.Print("no host found for IP ", hostIP)
|
||||
return ""
|
||||
return
|
||||
}
|
||||
|
||||
return host.Name
|
||||
return host.Name, nil
|
||||
}
|
||||
|
||||
func wsReadConfig(resp *restful.Response) *localconfig.Config {
|
||||
|
Loading…
Reference in New Issue
Block a user