secrets migration
This commit is contained in:
		@ -40,7 +40,8 @@ func migrateSecrets() {
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := loadSecretData(sslCfg); err != nil {
 | 
			
		||||
	secretData, err := loadSecretData(sslCfg)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		log.Fatal(err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
@ -66,10 +67,22 @@ func migrateSecrets() {
 | 
			
		||||
			clusterCAs.Put(clusterName+"/"+caName, CA{Key: ca.Key, Cert: ca.Cert})
 | 
			
		||||
 | 
			
		||||
			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)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,11 +13,6 @@ import (
 | 
			
		||||
	"github.com/cloudflare/cfssl/log"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	secretData *SecretData
 | 
			
		||||
	DontSave   = false
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type SecretData struct {
 | 
			
		||||
	clusters map[string]*ClusterSecrets
 | 
			
		||||
	config   *config.Config
 | 
			
		||||
@ -40,10 +35,10 @@ func secretDataPath() string {
 | 
			
		||||
	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")
 | 
			
		||||
 | 
			
		||||
	sd := &SecretData{
 | 
			
		||||
	sd = &SecretData{
 | 
			
		||||
		clusters: make(map[string]*ClusterSecrets),
 | 
			
		||||
		config:   config,
 | 
			
		||||
	}
 | 
			
		||||
@ -52,7 +47,6 @@ func loadSecretData(config *config.Config) (err error) {
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		if os.IsNotExist(err) {
 | 
			
		||||
			err = nil
 | 
			
		||||
			secretData = sd
 | 
			
		||||
			return
 | 
			
		||||
		}
 | 
			
		||||
		return
 | 
			
		||||
@ -62,7 +56,6 @@ func loadSecretData(config *config.Config) (err error) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	secretData = sd
 | 
			
		||||
	return
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -2,10 +2,6 @@ package main
 | 
			
		||||
 | 
			
		||||
import "testing"
 | 
			
		||||
 | 
			
		||||
func init() {
 | 
			
		||||
	DontSave = true
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSSHKeyGet(t *testing.T) {
 | 
			
		||||
	// TODO needs fake secret store
 | 
			
		||||
	// if _, err := getSSHKeyPairs("host"); err != nil {
 | 
			
		||||
 | 
			
		||||
@ -2,10 +2,12 @@ package main
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"log"
 | 
			
		||||
	"sort"
 | 
			
		||||
	"net/url"
 | 
			
		||||
	"strconv"
 | 
			
		||||
 | 
			
		||||
	restful "github.com/emicklei/go-restful"
 | 
			
		||||
 | 
			
		||||
	"novit.tech/direktil/local-server/pkg/mime"
 | 
			
		||||
	"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) {
 | 
			
		||||
	cs := secretData.clusters[req.PathParameter("cluster-name")]
 | 
			
		||||
	if cs == nil {
 | 
			
		||||
		wsNotFound(resp)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ca := cs.CAs[req.PathParameter("ca-name")]
 | 
			
		||||
	if ca == nil {
 | 
			
		||||
	clusterName := req.PathParameter("cluster-name")
 | 
			
		||||
	caName := req.PathParameter("ca-name")
 | 
			
		||||
 | 
			
		||||
	ca, found, err := clusterCAs.Get(clusterName + "/" + caName)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		wsError(resp, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
	if !found {
 | 
			
		||||
		wsNotFound(resp)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	resp.Header().Set("Content-Type", mime.CERT)
 | 
			
		||||
	resp.Write(ca.Cert)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func wsClusterSignedCert(req *restful.Request, resp *restful.Response) {
 | 
			
		||||
	cs := secretData.clusters[req.PathParameter("cluster-name")]
 | 
			
		||||
	if cs == nil {
 | 
			
		||||
		wsNotFound(resp)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	ca := cs.CAs[req.PathParameter("ca-name")]
 | 
			
		||||
	if ca == nil {
 | 
			
		||||
		wsNotFound(resp)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	clusterName := req.PathParameter("cluster-name")
 | 
			
		||||
	caName := req.PathParameter("ca-name")
 | 
			
		||||
	name := req.QueryParameter("name")
 | 
			
		||||
 | 
			
		||||
	if name == "" {
 | 
			
		||||
		keys := make([]string, 0, len(ca.Signed))
 | 
			
		||||
		for k := range ca.Signed {
 | 
			
		||||
			keys = append(keys, k)
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		sort.Strings(keys)
 | 
			
		||||
 | 
			
		||||
		resp.WriteJson(keys, restful.MIME_JSON)
 | 
			
		||||
	kc, found, err := clusterCASignedKeys.Get(clusterName + "/" + caName + "/" + name)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		wsError(resp, err)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	kc := ca.Signed[name]
 | 
			
		||||
	if kc == nil {
 | 
			
		||||
	if !found {
 | 
			
		||||
		wsNotFound(resp)
 | 
			
		||||
		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)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -18,6 +18,10 @@
 | 
			
		||||
    overflow: auto;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.cluster {
 | 
			
		||||
    max-width: 50%;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#store-infos {
 | 
			
		||||
    display: flex;
 | 
			
		||||
    flex-flow: row wrap;
 | 
			
		||||
 | 
			
		||||
@ -21,17 +21,15 @@ export default {
 | 
			
		||||
    <Downloads :token="token" :state="state" kind="cluster" :name="cluster.Name" />
 | 
			
		||||
  </section>
 | 
			
		||||
  <div class="section">CAs</div>
 | 
			
		||||
  <section v-for="ca in cluster.CAs">
 | 
			
		||||
    {{ ca.Name }}:
 | 
			
		||||
        <GetCopy :token="token" name="cert" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/certificate'" />
 | 
			
		||||
        <template v-if="ca.Signed">
 | 
			
		||||
          {{" "}}signed
 | 
			
		||||
          <template v-for="signed in ca.Signed">
 | 
			
		||||
            {{" "}}
 | 
			
		||||
            <GetCopy :token="token" :name="signed" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/signed?name='+signed" />
 | 
			
		||||
          </template>
 | 
			
		||||
        </template>
 | 
			
		||||
  </section>
 | 
			
		||||
  <table><tr><th>Name</th><th>Certificate</th><th>Signed certificates</th></tr>
 | 
			
		||||
  <tr v-for="ca in cluster.CAs">
 | 
			
		||||
    <td>{{ ca.Name }}</td>
 | 
			
		||||
    <td><GetCopy :token="token" name="cert" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/certificate'" /></td>
 | 
			
		||||
    <td><template v-for="signed in ca.Signed">
 | 
			
		||||
      {{" "}}
 | 
			
		||||
      <GetCopy :token="token" :name="signed" :href="'/clusters/'+cluster.Name+'/CAs/'+ca.Name+'/signed?name='+signed" />
 | 
			
		||||
    </template></td>
 | 
			
		||||
  </tr></table>
 | 
			
		||||
</div>
 | 
			
		||||
`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -124,6 +124,9 @@ header .utils > * {
 | 
			
		||||
.sheets section {
 | 
			
		||||
    margin: 2pt 6pt 6pt 6pt;
 | 
			
		||||
}
 | 
			
		||||
.sheets > *:last-child > table:last-child > tr:last-child > td {
 | 
			
		||||
    border-bottom: none;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.notif {
 | 
			
		||||
    display: inline-block;
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user