2023-07-11 20:59:02 +02:00
|
|
|
package env_v0_3
|
2022-07-26 22:00:59 +02:00
|
|
|
|
|
|
|
import (
|
2023-07-13 20:26:35 +02:00
|
|
|
"encoding/json"
|
|
|
|
"github.com/openziti/zrok/environment/env_core"
|
2023-01-09 20:16:08 +01:00
|
|
|
"github.com/pkg/errors"
|
2022-07-26 22:00:59 +02:00
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
)
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
const V = "v0.3"
|
|
|
|
|
2023-07-10 22:41:16 +02:00
|
|
|
type Root struct {
|
2023-07-13 20:26:35 +02:00
|
|
|
meta *env_core.Metadata
|
|
|
|
cfg *env_core.Config
|
|
|
|
env *env_core.Environment
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-14 16:51:35 +02:00
|
|
|
func Assert() (bool, error) {
|
|
|
|
exists, err := rootExists()
|
|
|
|
if err != nil {
|
|
|
|
return true, err
|
|
|
|
}
|
|
|
|
if exists {
|
|
|
|
meta, err := loadMetadata()
|
|
|
|
if err != nil {
|
|
|
|
return true, err
|
|
|
|
}
|
|
|
|
return meta.V == V, nil
|
|
|
|
}
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func Load() (*Root, error) {
|
|
|
|
r := &Root{}
|
|
|
|
exists, err := rootExists()
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return nil, err
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
if exists {
|
|
|
|
if meta, err := loadMetadata(); err == nil {
|
|
|
|
r.meta = meta
|
|
|
|
} else {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
if cfg, err := loadConfig(); err == nil {
|
|
|
|
r.cfg = cfg
|
|
|
|
}
|
|
|
|
|
|
|
|
if env, err := loadEnvironment(); err == nil {
|
|
|
|
r.env = env
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
root, err := rootDir()
|
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
r.meta = &env_core.Metadata{
|
|
|
|
V: V,
|
|
|
|
RootPath: root,
|
|
|
|
}
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
return r, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func rootExists() (bool, error) {
|
|
|
|
mf, err := metadataFile()
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return false, err
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
_, err = os.Stat(mf)
|
|
|
|
if os.IsNotExist(err) {
|
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return false, err
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-14 16:51:35 +02:00
|
|
|
return true, nil
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-14 15:57:40 +02:00
|
|
|
func assertMetadata() error {
|
|
|
|
exists, err := rootExists()
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if !exists {
|
|
|
|
if err := writeMetadata(); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func loadMetadata() (*env_core.Metadata, error) {
|
|
|
|
mf, err := metadataFile()
|
|
|
|
if err != nil {
|
2023-01-09 22:28:54 +01:00
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
data, err := os.ReadFile(mf)
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
m := &metadata{}
|
|
|
|
if err := json.Unmarshal(data, m); err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "error unmarshaling metadata file '%v'", mf)
|
|
|
|
}
|
|
|
|
if m.V != V {
|
|
|
|
return nil, errors.Errorf("got metadata version '%v', expected '%v'", m.V, V)
|
|
|
|
}
|
|
|
|
rf, err := rootDir()
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
out := &env_core.Metadata{
|
|
|
|
V: m.V,
|
|
|
|
RootPath: rf,
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
return out, nil
|
|
|
|
}
|
2023-01-09 20:16:08 +01:00
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func writeMetadata() error {
|
|
|
|
mf, err := metadataFile()
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return err
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
data, err := json.Marshal(&metadata{V: V})
|
|
|
|
if err != nil {
|
|
|
|
return err
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
if err := os.MkdirAll(filepath.Dir(mf), os.FileMode(0700)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
if err := os.WriteFile(mf, data, os.FileMode(0600)); err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
return nil
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func loadConfig() (*env_core.Config, error) {
|
|
|
|
cf, err := configFile()
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrap(err, "error getting config file path")
|
2023-01-09 22:28:54 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
data, err := os.ReadFile(cf)
|
|
|
|
if err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "error reading config file '%v'", cf)
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
cfg := &config{}
|
|
|
|
if err := json.Unmarshal(data, cfg); err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "error unmarshaling config file '%v'", cf)
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
out := &env_core.Config{
|
|
|
|
ApiEndpoint: cfg.ApiEndpoint,
|
|
|
|
}
|
|
|
|
return out, nil
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func saveConfig(cfg *env_core.Config) error {
|
|
|
|
in := &config{ApiEndpoint: cfg.ApiEndpoint}
|
|
|
|
data, err := json.MarshalIndent(in, "", " ")
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return errors.Wrap(err, "error marshaling config")
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
cf, err := configFile()
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "error getting config file path")
|
|
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(cf), os.FileMode(0700)); err != nil {
|
|
|
|
return errors.Wrapf(err, "error creating environment path '%v'", filepath.Dir(cf))
|
|
|
|
}
|
|
|
|
if err := os.WriteFile(cf, data, os.FileMode(0600)); err != nil {
|
|
|
|
return errors.Wrap(err, "error saving config file")
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func isEnabled() (bool, error) {
|
|
|
|
ef, err := environmentFile()
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return false, errors.Wrap(err, "error getting environment file path")
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
_, err = os.Stat(ef)
|
2023-01-09 23:37:43 +01:00
|
|
|
if os.IsNotExist(err) {
|
2023-07-13 20:26:35 +02:00
|
|
|
return false, nil
|
|
|
|
}
|
|
|
|
if err != nil {
|
|
|
|
return false, errors.Wrapf(err, "error stat-ing environment file '%v'", ef)
|
2023-01-09 23:37:43 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
return true, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func loadEnvironment() (*env_core.Environment, error) {
|
|
|
|
ef, err := environmentFile()
|
2023-01-09 23:37:43 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return nil, errors.Wrap(err, "error getting environment file")
|
2023-01-09 23:37:43 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
data, err := os.ReadFile(ef)
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return nil, errors.Wrapf(err, "error reading environment file '%v'", ef)
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
env := &environment{}
|
|
|
|
if err := json.Unmarshal(data, env); err != nil {
|
|
|
|
return nil, errors.Wrapf(err, "error unmarshaling environment file '%v'", ef)
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
out := &env_core.Environment{
|
|
|
|
Token: env.Token,
|
|
|
|
ZitiIdentity: env.ZId,
|
|
|
|
ApiEndpoint: env.ApiEndpoint,
|
|
|
|
}
|
|
|
|
return out, nil
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func saveEnvironment(env *env_core.Environment) error {
|
|
|
|
in := &environment{
|
|
|
|
Token: env.Token,
|
|
|
|
ZId: env.ZitiIdentity,
|
|
|
|
ApiEndpoint: env.ApiEndpoint,
|
|
|
|
}
|
|
|
|
data, err := json.MarshalIndent(in, "", " ")
|
2023-01-09 17:28:26 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return errors.Wrap(err, "error marshaling environment")
|
2023-01-09 17:28:26 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
ef, err := environmentFile()
|
2022-07-26 22:00:59 +02:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return errors.Wrap(err, "error getting environment file")
|
|
|
|
}
|
|
|
|
if err := os.MkdirAll(filepath.Dir(ef), os.FileMode(0700)); err != nil {
|
|
|
|
return errors.Wrapf(err, "error creating environment path '%v'", filepath.Dir(ef))
|
2022-07-26 22:00:59 +02:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
if err := os.WriteFile(ef, data, os.FileMode(0600)); err != nil {
|
|
|
|
return errors.Wrap(err, "error saving environment file")
|
|
|
|
}
|
|
|
|
return nil
|
2022-07-26 22:00:59 +02:00
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
func deleteEnvironment() error {
|
|
|
|
ef, err := environmentFile()
|
2023-01-09 20:16:08 +01:00
|
|
|
if err != nil {
|
2023-07-13 20:26:35 +02:00
|
|
|
return errors.Wrap(err, "error getting environment file")
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
2023-07-13 20:26:35 +02:00
|
|
|
if err := os.Remove(ef); err != nil {
|
|
|
|
return errors.Wrap(err, "error removing environment file")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
type metadata struct {
|
|
|
|
V string `json:"v"`
|
2023-01-09 20:16:08 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
type config struct {
|
|
|
|
ApiEndpoint string `json:"api_endpoint"`
|
2023-01-09 22:28:54 +01:00
|
|
|
}
|
|
|
|
|
2023-07-13 20:26:35 +02:00
|
|
|
type environment struct {
|
|
|
|
Token string `json:"zrok_token"`
|
|
|
|
ZId string `json:"ziti_identity"`
|
|
|
|
ApiEndpoint string `json:"api_endpoint"`
|
2022-07-26 22:00:59 +02:00
|
|
|
}
|