cmd/utils/config/node.go (110 lines of code) (raw):

// Copyright (c) Microsoft Corporation. // Licensed under the MIT License. package config import ( "bytes" "encoding/json" "errors" "fmt" "io/fs" "os" ) // UseNodeConfig sets the current node to use in the configuration func (c *config) UseNodeConfig(targetNode string) error { if err := c.ReadInConfig(); err != nil && !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("reading config: %w", err) } if !c.IsSet("nodes." + targetNode) { return fmt.Errorf("node %q not found", targetNode) } c.Set(currentNodeKey, targetNode) if err := c.WriteConfig(); err != nil { return fmt.Errorf("writing config: %w", err) } return nil } // UnsetCurrentNodeConfig removes the current node from the configuration func (c *config) UnsetCurrentNodeConfig() error { if err := c.ReadInConfig(); err != nil && !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("reading config: %w", err) } if c.IsSet(currentNodeKey) { if err := c.deleteCurrentNodeConfig(); err != nil { return fmt.Errorf("deleting current node config: %w", err) } if err := c.WriteConfig(); err != nil { return fmt.Errorf("writing config: %w", err) } } return nil } // UnsetNodeConfig removes the node configuration func (c *config) UnsetNodeConfig(targetNode string) error { if err := c.ReadInConfig(); err != nil && !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("reading config: %w", err) } if c.IsSet("nodes." + targetNode) { if err := c.deleteNodeConfig(targetNode); err != nil { return fmt.Errorf("deleting node config: %w", err) } if err := c.WriteConfig(); err != nil { return fmt.Errorf("writing config: %w", err) } } return nil } // SetNodeConfigWithNodeFlag sets the node configuration with based on node flag func (c *config) SetNodeConfigWithNodeFlag(nodeName, nodeFlag string) error { return c.setNodeConfig(nodeName, nodeFlag, "", "", "", "", "") } // SetNodeConfigWithResourceIDFlag sets the node configuration with based on resource ID flag func (c *config) SetNodeConfigWithResourceIDFlag(nodeName, resourceIDFlag string) error { return c.setNodeConfig(nodeName, "", resourceIDFlag, "", "", "", "") } // SetNodeConfigWithVMSSInfoFlag sets the node configuration with vmss info flags func (c *config) SetNodeConfigWithVMSSInfoFlag(nodeName, subscriptionIDFlag, nodeResourceGroupFlag, vmssFlag, instanceIDFlag string) error { return c.setNodeConfig(nodeName, "", "", subscriptionIDFlag, nodeResourceGroupFlag, vmssFlag, instanceIDFlag) } func (c *config) setNodeConfig(nodeName, nodeFlag, resourceIDFlag, subscriptionIDFlag, nodeResourceGroupFlag, vmssFlag, instanceIDFlag string, ) error { if err := os.MkdirAll(Dir(), 0o700); err != nil { return fmt.Errorf("creating config directory: %w", err) } if err := c.ReadInConfig(); err != nil && !errors.Is(err, fs.ErrNotExist) { return fmt.Errorf("reading config: %w", err) } // delete the node config if it already exists to avoid mutually exclusive config if c.IsSet("nodes." + nodeName) { if err := c.deleteNodeConfig(nodeName); err != nil { return fmt.Errorf("deleting node config: %w", err) } } if nodeFlag != "" { c.Set("nodes."+nodeName+".node", nodeFlag) } else if resourceIDFlag != "" { c.Set("nodes."+nodeName+".id", resourceIDFlag) } else { c.Set("nodes."+nodeName+".subscription", subscriptionIDFlag) c.Set("nodes."+nodeName+".node-resource-group", nodeResourceGroupFlag) c.Set("nodes."+nodeName+".vmss", vmssFlag) c.Set("nodes."+nodeName+".instance-id", instanceIDFlag) } if err := c.WriteConfig(); err != nil { return fmt.Errorf("writing config: %w", err) } return nil } func (c *config) deleteNodeConfig(targetNode string) error { return c.deleteConfig(func(settings map[string]interface{}) { delete(settings["nodes"].(map[string]interface{}), targetNode) }) } func (c *config) deleteCurrentNodeConfig() error { return c.deleteConfig(func(settings map[string]interface{}) { delete(settings, currentNodeKey) }) } // deleteConfig, viper does not support deleting a config with key, so we get // the underlying map, delete the key via deleteKey and then re-read the config // https://github.com/spf13/viper/issues/632#issuecomment-869668629 func (c *config) deleteConfig(deleteKey func(setting map[string]interface{})) error { settings := c.AllSettings() deleteKey(settings) data, err := json.MarshalIndent(settings, "", " ") if err != nil { return fmt.Errorf("marshalling config: %w", err) } if err = c.ReadConfig(bytes.NewReader(data)); err != nil { return fmt.Errorf("reading config: %w", err) } return nil }