k3s/pkg/daemons/control/bootstrap.go

101 lines
2.1 KiB
Go

package control
import (
"context"
"encoding/json"
"io/ioutil"
"os"
"path/filepath"
"github.com/pkg/errors"
"github.com/rancher/k3s/pkg/daemons/config"
"github.com/rancher/kine/pkg/client"
"github.com/sirupsen/logrus"
)
const (
k3sRuntimeEtcdPath = "/k3s/runtime"
)
// fetchBootstrapData copies the bootstrap data (certs, keys, passwords)
// from etcd to individual files specified by cfg.Runtime.
func fetchBootstrapData(ctx context.Context, cfg *config.Control, c client.Client) error {
logrus.Info("Fetching bootstrap data from etcd")
gr, err := c.Get(ctx, k3sRuntimeEtcdPath)
if err != nil {
return err
}
if gr.Modified == 0 {
return nil
}
paths, err := objToMap(&cfg.Runtime.ControlRuntimeBootstrap)
if err != nil {
return err
}
files := map[string][]byte{}
if err := json.Unmarshal(gr.Data, &files); err != nil {
return err
}
for pathKey, data := range files {
path, ok := paths[pathKey]
if !ok {
continue
}
if err := os.MkdirAll(filepath.Dir(path), 0700); err != nil {
return errors.Wrapf(err, "failed to mkdir %s", filepath.Dir(path))
}
if err := ioutil.WriteFile(path, data, 0700); err != nil {
return errors.Wrapf(err, "failed to write to %s", path)
}
}
return nil
}
// storeBootstrapData copies the bootstrap data in the opposite direction to
// fetchBootstrapData.
func storeBootstrapData(ctx context.Context, cfg *config.Control, client client.Client) error {
if cfg.BootstrapReadOnly {
return nil
}
paths, err := objToMap(&cfg.Runtime.ControlRuntimeBootstrap)
if err != nil {
return nil
}
dataMap := map[string][]byte{}
for pathKey, path := range paths {
if path == "" {
continue
}
data, err := ioutil.ReadFile(path)
if err != nil {
return errors.Wrapf(err, "failed to read %s", path)
}
dataMap[pathKey] = data
}
bytes, err := json.Marshal(dataMap)
if err != nil {
return err
}
return client.Put(ctx, k3sRuntimeEtcdPath, bytes)
}
func objToMap(obj interface{}) (map[string]string, error) {
bytes, err := json.Marshal(obj)
if err != nil {
return nil, err
}
data := map[string]string{}
return data, json.Unmarshal(bytes, &data)
}