secrets migration

This commit is contained in:
Mikaël Cluseau 2023-02-15 08:49:34 +01:00
parent 1f03315897
commit 26953cf703
7 changed files with 55 additions and 60 deletions

View File

@ -40,7 +40,8 @@ func migrateSecrets() {
} }
} }
if err := loadSecretData(sslCfg); err != nil { secretData, err := loadSecretData(sslCfg)
if err != nil {
log.Fatal(err) log.Fatal(err)
return return
} }
@ -66,10 +67,22 @@ func migrateSecrets() {
clusterCAs.Put(clusterName+"/"+caName, CA{Key: ca.Key, Cert: ca.Cert}) clusterCAs.Put(clusterName+"/"+caName, CA{Key: ca.Key, Cert: ca.Cert})
for signedName, signed := range ca.Signed { for signedName, signed := range ca.Signed {
clusterCASignedKeys.Put(clusterName+"/"+caName+"/"+signedName, *signed) err = clusterCASignedKeys.Put(clusterName+"/"+caName+"/"+signedName, *signed)
if err != nil {
log.Fatal(err)
}
} }
} }
// TODO for hostName, pairs := range cluster.SSHKeyPairs {
err = sshHostKeys.Put(hostName, pairs)
if err != nil {
log.Fatal(err)
}
}
}
if err := os.Rename(secretDataPath(), secretDataPath()+".migrated"); err != nil {
log.Fatal("failed to rename migrated secrets: ", err)
} }
} }

View File

@ -13,11 +13,6 @@ import (
"github.com/cloudflare/cfssl/log" "github.com/cloudflare/cfssl/log"
) )
var (
secretData *SecretData
DontSave = false
)
type SecretData struct { type SecretData struct {
clusters map[string]*ClusterSecrets clusters map[string]*ClusterSecrets
config *config.Config config *config.Config
@ -40,10 +35,10 @@ func secretDataPath() string {
return filepath.Join(*dataDir, "secret-data.json") return filepath.Join(*dataDir, "secret-data.json")
} }
func loadSecretData(config *config.Config) (err error) { func loadSecretData(config *config.Config) (sd *SecretData, err error) {
log.Info("Loading secret data") log.Info("Loading secret data")
sd := &SecretData{ sd = &SecretData{
clusters: make(map[string]*ClusterSecrets), clusters: make(map[string]*ClusterSecrets),
config: config, config: config,
} }
@ -52,7 +47,6 @@ func loadSecretData(config *config.Config) (err error) {
if err != nil { if err != nil {
if os.IsNotExist(err) { if os.IsNotExist(err) {
err = nil err = nil
secretData = sd
return return
} }
return return
@ -62,7 +56,6 @@ func loadSecretData(config *config.Config) (err error) {
return return
} }
secretData = sd
return return
} }

View File

@ -2,10 +2,6 @@ package main
import "testing" import "testing"
func init() {
DontSave = true
}
func TestSSHKeyGet(t *testing.T) { func TestSSHKeyGet(t *testing.T) {
// TODO needs fake secret store // TODO needs fake secret store
// if _, err := getSSHKeyPairs("host"); err != nil { // if _, err := getSSHKeyPairs("host"); err != nil {

View File

@ -2,10 +2,12 @@ package main
import ( import (
"log" "log"
"sort" "net/url"
"strconv"
restful "github.com/emicklei/go-restful" restful "github.com/emicklei/go-restful"
"novit.tech/direktil/local-server/pkg/mime"
"novit.tech/direktil/pkg/localconfig" "novit.tech/direktil/pkg/localconfig"
) )
@ -83,53 +85,39 @@ func wsClusterAddons(req *restful.Request, resp *restful.Response) {
} }
func wsClusterCACert(req *restful.Request, resp *restful.Response) { func wsClusterCACert(req *restful.Request, resp *restful.Response) {
cs := secretData.clusters[req.PathParameter("cluster-name")] clusterName := req.PathParameter("cluster-name")
if cs == nil { caName := req.PathParameter("ca-name")
wsNotFound(resp)
return ca, found, err := clusterCAs.Get(clusterName + "/" + caName)
} if err != nil {
wsError(resp, err)
ca := cs.CAs[req.PathParameter("ca-name")] return
if ca == nil { }
if !found {
wsNotFound(resp) wsNotFound(resp)
return return
} }
resp.Header().Set("Content-Type", mime.CERT)
resp.Write(ca.Cert) resp.Write(ca.Cert)
} }
func wsClusterSignedCert(req *restful.Request, resp *restful.Response) { func wsClusterSignedCert(req *restful.Request, resp *restful.Response) {
cs := secretData.clusters[req.PathParameter("cluster-name")] clusterName := req.PathParameter("cluster-name")
if cs == nil { caName := req.PathParameter("ca-name")
wsNotFound(resp)
return
}
ca := cs.CAs[req.PathParameter("ca-name")]
if ca == nil {
wsNotFound(resp)
return
}
name := req.QueryParameter("name") name := req.QueryParameter("name")
if name == "" { kc, found, err := clusterCASignedKeys.Get(clusterName + "/" + caName + "/" + name)
keys := make([]string, 0, len(ca.Signed)) if err != nil {
for k := range ca.Signed { wsError(resp, err)
keys = append(keys, k)
}
sort.Strings(keys)
resp.WriteJson(keys, restful.MIME_JSON)
return return
} }
if !found {
kc := ca.Signed[name]
if kc == nil {
wsNotFound(resp) wsNotFound(resp)
return return
} }
resp.AddHeader("Content-Type", mime.CERT)
resp.AddHeader("Content-Disposition", "attachment; filename="+strconv.Quote(clusterName+"_"+caName+"_"+url.PathEscape(name)+".crt"))
resp.Write(kc.Cert) resp.Write(kc.Cert)
} }

View File

@ -18,6 +18,10 @@
overflow: auto; overflow: auto;
} }
.cluster {
max-width: 50%;
}
#store-infos { #store-infos {
display: flex; display: flex;
flex-flow: row wrap; flex-flow: row wrap;

View File

@ -21,17 +21,15 @@ export default {
<Downloads :token="token" :state="state" kind="cluster" :name="cluster.Name" /> <Downloads :token="token" :state="state" kind="cluster" :name="cluster.Name" />
</section> </section>
<div class="section">CAs</div> <div class="section">CAs</div>
<section v-for="ca in cluster.CAs"> <table><tr><th>Name</th><th>Certificate</th><th>Signed certificates</th></tr>
{{ ca.Name }}: <tr v-for="ca in cluster.CAs">
<GetCopy :token="token" name="cert" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/certificate'" /> <td>{{ ca.Name }}</td>
<template v-if="ca.Signed"> <td><GetCopy :token="token" name="cert" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/certificate'" /></td>
{{" "}}signed <td><template v-for="signed in ca.Signed">
<template v-for="signed in ca.Signed">
{{" "}} {{" "}}
<GetCopy :token="token" :name="signed" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/signed?name='+signed" /> <GetCopy :token="token" :name="signed" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/signed?name='+signed" />
</template> </template></td>
</template> </tr></table>
</section>
</div> </div>
` `
} }

View File

@ -124,6 +124,9 @@ header .utils > * {
.sheets section { .sheets section {
margin: 2pt 6pt 6pt 6pt; margin: 2pt 6pt 6pt 6pt;
} }
.sheets > *:last-child > table:last-child > tr:last-child > td {
border-bottom: none;
}
.notif { .notif {
display: inline-block; display: inline-block;