dls: password support
This commit is contained in:
parent
6a0cd6da02
commit
456722a616
@ -160,6 +160,10 @@ func (ctx *renderContext) templateFuncs(ctxMap map[string]interface{}) map[strin
|
|||||||
}
|
}
|
||||||
|
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
|
"password": func(name string) (s string) {
|
||||||
|
return fmt.Sprintf("{{ password %q %q }}", cluster, name)
|
||||||
|
},
|
||||||
|
|
||||||
"token": func(name string) (s string) {
|
"token": func(name string) (s string) {
|
||||||
return fmt.Sprintf("{{ token %q %q }}", cluster, name)
|
return fmt.Sprintf("{{ token %q %q }}", cluster, name)
|
||||||
},
|
},
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"encoding/hex"
|
"encoding/hex"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
@ -135,6 +136,14 @@ func (ctx *renderContext) templateFuncs() map[string]interface{} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return map[string]interface{}{
|
return map[string]interface{}{
|
||||||
|
"password": func(cluster, name string) (password string, err error) {
|
||||||
|
password = secretData.Password(cluster, name)
|
||||||
|
if len(password) == 0 {
|
||||||
|
err = fmt.Errorf("password %q not defined for cluster %q", name, cluster)
|
||||||
|
}
|
||||||
|
return
|
||||||
|
},
|
||||||
|
|
||||||
"token": func(cluster, name string) (s string, err error) {
|
"token": func(cluster, name string) (s string, err error) {
|
||||||
return secretData.Token(cluster, name)
|
return secretData.Token(cluster, name)
|
||||||
},
|
},
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"net"
|
"net"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"sort"
|
||||||
"sync"
|
"sync"
|
||||||
|
|
||||||
"github.com/cloudflare/cfssl/config"
|
"github.com/cloudflare/cfssl/config"
|
||||||
@ -36,8 +37,9 @@ type SecretData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ClusterSecrets struct {
|
type ClusterSecrets struct {
|
||||||
CAs map[string]*CA
|
CAs map[string]*CA
|
||||||
Tokens map[string]string
|
Tokens map[string]string
|
||||||
|
Passwords map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
type CA struct {
|
type CA struct {
|
||||||
@ -101,6 +103,14 @@ func (sd *SecretData) Save() error {
|
|||||||
return ioutil.WriteFile(secretDataPath(), ba, 0600)
|
return ioutil.WriteFile(secretDataPath(), ba, 0600)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newClusterSecrets() *ClusterSecrets {
|
||||||
|
return &ClusterSecrets{
|
||||||
|
CAs: make(map[string]*CA),
|
||||||
|
Tokens: make(map[string]string),
|
||||||
|
Passwords: make(map[string]string),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (sd *SecretData) cluster(name string) (cs *ClusterSecrets) {
|
func (sd *SecretData) cluster(name string) (cs *ClusterSecrets) {
|
||||||
cs, ok := sd.clusters[name]
|
cs, ok := sd.clusters[name]
|
||||||
if ok {
|
if ok {
|
||||||
@ -112,15 +122,47 @@ func (sd *SecretData) cluster(name string) (cs *ClusterSecrets) {
|
|||||||
|
|
||||||
log.Info("secret-data: new cluster: ", name)
|
log.Info("secret-data: new cluster: ", name)
|
||||||
|
|
||||||
cs = &ClusterSecrets{
|
cs = newClusterSecrets()
|
||||||
CAs: make(map[string]*CA),
|
|
||||||
Tokens: make(map[string]string),
|
|
||||||
}
|
|
||||||
sd.clusters[name] = cs
|
sd.clusters[name] = cs
|
||||||
sd.changed = true
|
sd.changed = true
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (sd *SecretData) Passwords(cluster string) (passwords []string) {
|
||||||
|
cs := sd.cluster(cluster)
|
||||||
|
|
||||||
|
passwords = make([]string, 0, len(cs.Passwords))
|
||||||
|
for name := range cs.Passwords {
|
||||||
|
passwords = append(passwords, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Strings(passwords)
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sd *SecretData) Password(cluster, name string) (password string) {
|
||||||
|
cs := sd.cluster(cluster)
|
||||||
|
|
||||||
|
if cs.Passwords == nil {
|
||||||
|
cs.Passwords = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
password = cs.Passwords[name]
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func (sd *SecretData) SetPassword(cluster, name, password string) {
|
||||||
|
cs := sd.cluster(cluster)
|
||||||
|
|
||||||
|
if cs.Passwords == nil {
|
||||||
|
cs.Passwords = make(map[string]string)
|
||||||
|
}
|
||||||
|
|
||||||
|
cs.Passwords[name] = password
|
||||||
|
sd.changed = true
|
||||||
|
}
|
||||||
|
|
||||||
func (sd *SecretData) Token(cluster, name string) (token string, err error) {
|
func (sd *SecretData) Token(cluster, name string) (token string, err error) {
|
||||||
cs := sd.cluster(cluster)
|
cs := sd.cluster(cluster)
|
||||||
|
|
||||||
|
@ -61,3 +61,42 @@ func wsClusterAddons(req *restful.Request, resp *restful.Response) {
|
|||||||
|
|
||||||
resp.Write([]byte(cluster.Addons))
|
resp.Write([]byte(cluster.Addons))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func wsClusterPasswords(req *restful.Request, resp *restful.Response) {
|
||||||
|
cluster := wsReadCluster(req, resp)
|
||||||
|
if cluster == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp.WriteEntity(secretData.Passwords(cluster.Name))
|
||||||
|
}
|
||||||
|
func wsClusterPassword(req *restful.Request, resp *restful.Response) {
|
||||||
|
cluster := wsReadCluster(req, resp)
|
||||||
|
if cluster == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name := req.PathParameter("password-name")
|
||||||
|
|
||||||
|
resp.WriteEntity(secretData.Password(cluster.Name, name))
|
||||||
|
}
|
||||||
|
func wsClusterSetPassword(req *restful.Request, resp *restful.Response) {
|
||||||
|
cluster := wsReadCluster(req, resp)
|
||||||
|
if cluster == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
name := req.PathParameter("password-name")
|
||||||
|
|
||||||
|
var password string
|
||||||
|
if err := req.ReadEntity(&password); err != nil {
|
||||||
|
wsError(resp, err) // FIXME this is a BadRequest
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
secretData.SetPassword(cluster.Name, name, password)
|
||||||
|
|
||||||
|
if err := secretData.Save(); err != nil {
|
||||||
|
wsError(resp, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -31,6 +31,13 @@ func buildWS() *restful.WebService {
|
|||||||
Returns(http.StatusOK, "OK", nil).
|
Returns(http.StatusOK, "OK", nil).
|
||||||
Returns(http.StatusNotFound, "The cluster does not exists or does not have addons defined", nil))
|
Returns(http.StatusNotFound, "The cluster does not exists or does not have addons defined", nil))
|
||||||
|
|
||||||
|
ws.Route(ws.GET("/clusters/{cluster-name}/passwords").Filter(adminAuth).To(wsClusterPasswords).
|
||||||
|
Doc("List cluster's passwords"))
|
||||||
|
ws.Route(ws.GET("/clusters/{cluster-name}/passwords/{password-name}").Filter(adminAuth).To(wsClusterPassword).
|
||||||
|
Doc("Get cluster's password"))
|
||||||
|
ws.Route(ws.PUT("/clusters/{cluster-name}/passwords/{password-name}").Filter(adminAuth).To(wsClusterSetPassword).
|
||||||
|
Doc("Set cluster's password"))
|
||||||
|
|
||||||
// hosts API
|
// hosts API
|
||||||
ws.Route(ws.GET("/hosts").Filter(hostsAuth).To(wsListHosts).
|
ws.Route(ws.GET("/hosts").Filter(hostsAuth).To(wsListHosts).
|
||||||
Doc("List hosts"))
|
Doc("List hosts"))
|
||||||
|
Loading…
Reference in New Issue
Block a user