mirror of
https://github.com/micromdm/micromdm/
synced 2026-08-05 08:55:51 +08:00
Added ability to store multiple servers and switch between them (#275)
Added ability to store multiple servers, switch between them and migrate old config format to new config format. Closes #189
This commit is contained in:
committed by
Victor Vrantchan
parent
777f9af8f0
commit
a3e228fbbe
@@ -20,12 +20,12 @@ import (
|
||||
)
|
||||
|
||||
type applyCommand struct {
|
||||
config *ClientConfig
|
||||
config *ServerConfig
|
||||
applysvc apply.Service
|
||||
}
|
||||
|
||||
func (cmd *applyCommand) setup() error {
|
||||
cfg, err := LoadClientConfig()
|
||||
cfg, err := LoadServerConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -14,6 +14,8 @@ import (
|
||||
|
||||
"crypto/tls"
|
||||
"net/http"
|
||||
|
||||
"github.com/pkg/errors"
|
||||
)
|
||||
|
||||
type configCommand struct {
|
||||
@@ -37,16 +39,18 @@ func (cmd *configCommand) Run(args []string) error {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
var config *ClientConfig
|
||||
if cfg, err := LoadClientConfig(); err == nil {
|
||||
config = cfg
|
||||
} else {
|
||||
config = new(ClientConfig)
|
||||
if strings.ToLower(args[0]) != "migrate" {
|
||||
checkForOldConfig()
|
||||
}
|
||||
var run func(*ClientConfig, []string) error
|
||||
|
||||
var run func([]string) error
|
||||
switch strings.ToLower(args[0]) {
|
||||
case "migrate":
|
||||
run = migrateCmd
|
||||
case "set":
|
||||
run = setCmd
|
||||
case "switch":
|
||||
run = switchCmd
|
||||
case "print":
|
||||
printConfig()
|
||||
return nil
|
||||
@@ -55,7 +59,7 @@ func (cmd *configCommand) Run(args []string) error {
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
return run(config, args[1:])
|
||||
return run(args[1:])
|
||||
}
|
||||
|
||||
func printConfig() {
|
||||
@@ -74,14 +78,56 @@ func (cmd *configCommand) Usage() error {
|
||||
const help = `
|
||||
mdmctl config print
|
||||
mdmctl config set -h
|
||||
mdmctl config switch -h
|
||||
`
|
||||
fmt.Println(help)
|
||||
return nil
|
||||
}
|
||||
|
||||
func setCmd(cfg *ClientConfig, args []string) error {
|
||||
func checkForOldConfig() error {
|
||||
configPath, err := namedClientConfigPath("default.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := os.Stat(configPath); !os.IsNotExist(err) {
|
||||
fmt.Println("Found old style config. You must migrate it to continue")
|
||||
fmt.Println("Run `mdmctl config migrate -name=myconfig`")
|
||||
os.Exit(1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
func migrateServerConfig(configName string) error {
|
||||
configPath, err := namedClientConfigPath("default.json")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfgData, err := ioutil.ReadFile(configPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
var serverCfg *ServerConfig
|
||||
err = json.Unmarshal(cfgData, &serverCfg)
|
||||
if err != nil {
|
||||
return errors.Wrapf(err, "failed to unmarshal %s", configPath)
|
||||
}
|
||||
if err = saveServerConfig(serverCfg, configName); err != nil {
|
||||
return err
|
||||
}
|
||||
if err = os.Remove(configPath); err != nil {
|
||||
return err
|
||||
}
|
||||
err = switchServerConfig(configName)
|
||||
if err != nil {
|
||||
fmt.Errorf("Failed to set %s as active config", configName)
|
||||
}
|
||||
fmt.Println("Successfully migrated old config.")
|
||||
return nil
|
||||
}
|
||||
|
||||
func setCmd(args []string) error {
|
||||
flagset := flag.NewFlagSet("set", flag.ExitOnError)
|
||||
var (
|
||||
flName = flagset.String("name", "", "name of the server")
|
||||
flToken = flagset.String("api-token", "", "api token to connect to micromdm server")
|
||||
flServerURL = flagset.String("server-url", "", "server url of micromdm server")
|
||||
flSkipVerify = flagset.Bool("skip-verify", false, "skip verification of server certificate (insecure)")
|
||||
@@ -92,6 +138,8 @@ func setCmd(cfg *ClientConfig, args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg := new(ServerConfig)
|
||||
|
||||
if *flToken != "" {
|
||||
cfg.APIToken = *flToken
|
||||
}
|
||||
@@ -104,7 +152,33 @@ func setCmd(cfg *ClientConfig, args []string) error {
|
||||
|
||||
cfg.SkipVerify = *flSkipVerify
|
||||
|
||||
return SaveClientConfig(cfg)
|
||||
return saveServerConfig(cfg, *flName)
|
||||
}
|
||||
|
||||
func switchCmd(args []string) error {
|
||||
flagset := flag.NewFlagSet("switch", flag.ExitOnError)
|
||||
var (
|
||||
flName = flagset.String("name", "", "name of the server to switch to")
|
||||
)
|
||||
|
||||
flagset.Usage = usageFor(flagset, "mdmctl config switch [flags]")
|
||||
if err := flagset.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return switchServerConfig(*flName)
|
||||
}
|
||||
func migrateCmd(args []string) error {
|
||||
flagset := flag.NewFlagSet("migrate", flag.ExitOnError)
|
||||
var (
|
||||
flName = flagset.String("name", "", "name of the server to switch to")
|
||||
)
|
||||
|
||||
if err := flagset.Parse(args); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return migrateServerConfig(*flName)
|
||||
}
|
||||
|
||||
func validateServerURL(serverURL string) (string, error) {
|
||||
@@ -125,14 +199,22 @@ func validateServerURL(serverURL string) (string, error) {
|
||||
}
|
||||
|
||||
func clientConfigPath() (string, error) {
|
||||
configPath, err := namedClientConfigPath("servers.json")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return configPath, err
|
||||
}
|
||||
|
||||
func namedClientConfigPath(fileName string) (string, error) {
|
||||
usr, err := user.Current()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return filepath.Join(usr.HomeDir, ".micromdm", "default.json"), err
|
||||
return filepath.Join(usr.HomeDir, ".micromdm", fileName), err
|
||||
}
|
||||
|
||||
func SaveClientConfig(cfg *ClientConfig) error {
|
||||
func saveClientConfig(clientCfg *ClientConfig) error {
|
||||
configPath, err := clientConfigPath()
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -147,23 +229,45 @@ func SaveClientConfig(cfg *ClientConfig) error {
|
||||
return err
|
||||
}
|
||||
defer f.Close()
|
||||
|
||||
if cfg == nil {
|
||||
cfg = new(ClientConfig)
|
||||
}
|
||||
enc := json.NewEncoder(f)
|
||||
enc.SetIndent("", " ")
|
||||
return enc.Encode(cfg)
|
||||
return enc.Encode(clientCfg)
|
||||
}
|
||||
|
||||
func LoadClientConfig() (*ClientConfig, error) {
|
||||
func saveServerConfig(cfg *ServerConfig, name string) error {
|
||||
clientCfg, err := loadClientConfig()
|
||||
if err != nil {
|
||||
if os.IsNotExist(errors.Cause(err)) {
|
||||
clientCfg = new(ClientConfig)
|
||||
clientCfg.Servers = make(map[string]ServerConfig)
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
}
|
||||
if cfg == nil {
|
||||
cfg = new(ServerConfig)
|
||||
}
|
||||
clientCfg.Servers[name] = *cfg
|
||||
return saveClientConfig(clientCfg)
|
||||
}
|
||||
|
||||
func switchServerConfig(name string) error {
|
||||
clientCfg, err := loadClientConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
clientCfg.Active = name
|
||||
return saveClientConfig(clientCfg)
|
||||
}
|
||||
|
||||
func loadClientConfig() (*ClientConfig, error) {
|
||||
path, err := clientConfigPath()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cfgData, err := ioutil.ReadFile(path)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to load default config file: %s", err)
|
||||
return nil, errors.Wrap(err, "unable to load default config file")
|
||||
}
|
||||
var cfg ClientConfig
|
||||
err = json.Unmarshal(cfgData, &cfg)
|
||||
@@ -173,7 +277,22 @@ func LoadClientConfig() (*ClientConfig, error) {
|
||||
return &cfg, nil
|
||||
}
|
||||
|
||||
func LoadServerConfig() (*ServerConfig, error) {
|
||||
cfg, err := loadClientConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var serverCfg ServerConfig
|
||||
serverCfg = cfg.Servers[cfg.Active]
|
||||
return &serverCfg, nil
|
||||
}
|
||||
|
||||
type ClientConfig struct {
|
||||
Active string `json:"active"`
|
||||
Servers map[string]ServerConfig `json:"servers"`
|
||||
}
|
||||
|
||||
type ServerConfig struct {
|
||||
APIToken string `json:"api_token"`
|
||||
ServerURL string `json:"server_url"`
|
||||
SkipVerify bool `json:"skip_verify"`
|
||||
|
||||
@@ -20,12 +20,12 @@ import (
|
||||
)
|
||||
|
||||
type getCommand struct {
|
||||
config *ClientConfig
|
||||
config *ServerConfig
|
||||
list list.Service
|
||||
}
|
||||
|
||||
func (cmd *getCommand) setup() error {
|
||||
cfg, err := LoadClientConfig()
|
||||
cfg, err := LoadServerConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -197,7 +197,7 @@ func (cmd *mdmcertCommand) runUpload(args []string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
cfg, err := LoadClientConfig()
|
||||
cfg, err := LoadServerConfig()
|
||||
if err != nil {
|
||||
return errors.Wrap(err, "load mdmctl client config")
|
||||
}
|
||||
|
||||
@@ -15,6 +15,9 @@ func main() {
|
||||
usage()
|
||||
os.Exit(1)
|
||||
}
|
||||
if strings.ToLower(os.Args[1]) != "config" {
|
||||
checkForOldConfig()
|
||||
}
|
||||
var run func([]string) error
|
||||
switch strings.ToLower(os.Args[1]) {
|
||||
case "version", "-version":
|
||||
|
||||
@@ -12,12 +12,12 @@ import (
|
||||
)
|
||||
|
||||
type removeCommand struct {
|
||||
config *ClientConfig
|
||||
config *ServerConfig
|
||||
remove remove.Service
|
||||
}
|
||||
|
||||
func (cmd *removeCommand) setup() error {
|
||||
cfg, err := LoadClientConfig()
|
||||
cfg, err := LoadServerConfig()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user