Persist airship config selection in airshipui.json file

This change:

1. Reads location of airship config file from "airshipConfigPath"
key in airshipui.json
2. If key does not exist, it is added to airshipui.json along with
the default path of $HOME/.airship/config
3. If a user initializes or specifies a config file in a different
location, that location will be written to airshipui.json and will
be used in place of the default

Change-Id: I1d4282be26729427d14de8b60778a347f5e4f681
This commit is contained in:
Matthew Fuller 2020-11-03 01:42:16 +00:00
parent e05b2efed0
commit d053e593ac
11 changed files with 85 additions and 48 deletions

View File

@ -1,4 +1,5 @@
{
"airshipConfigPath": "/home/ubuntu/.airship/config",
"webservice": {
"host": "<host>",
"port": <port>,

View File

@ -42,6 +42,7 @@ type Config struct {
AuthMethod *AuthMethod `json:"authMethod,omitempty"`
Dashboards []Dashboard `json:"dashboards,omitempty"`
Users map[string]string `json:"users,omitempty"`
AirshipConfigPath *string `json:"airshipConfigPath,omitempty"`
}
// AuthMethod structure to hold authentication parameters
@ -241,6 +242,28 @@ func SetUIConfig() error {
return checkConfigs()
}
// Persist saves the current UIConfig to the airshipui.json config file
func (c *Config) Persist() error {
bytes, err := json.Marshal(UIConfig)
if err != nil {
return err
}
return ioutil.WriteFile(UIConfigFile, bytes, 0600)
}
func createDefaultConfigPath() error {
home, err := os.UserHomeDir()
if err != nil {
return err
}
path := filepath.Join(home, ".airship", "config")
UIConfig.AirshipConfigPath = &path
return nil
}
// checkConfigs will work its way through the config file, if it exists, and creates defaults where needed
func checkConfigs() error {
writeFile := false
@ -279,6 +302,14 @@ func checkConfigs() error {
}
}
if UIConfig.AirshipConfigPath == nil {
writeFile = true
err := createDefaultConfigPath()
if err != nil {
return err
}
}
if writeFile {
bytes, err := json.Marshal(UIConfig)
if err != nil {

View File

@ -26,14 +26,6 @@ import (
"opendev.org/airship/airshipui/pkg/webservice"
)
// AirshipConfigPath location of airship config (default $HOME/.airship.config)
// TODO(mfuller): are we going to retrieve these from the environment / cli options?
// leaving them both unset (nil) for now so that the default locations will be used
var AirshipConfigPath *string
// KubeConfigPath location of kubeconfig used by airshipctl (default $HOME/.airship/kubeconfig)
var KubeConfigPath *string
const (
AirshipConfigNotFoundErr = `No airship config file found.
Please visit the Config section to specify or initialize a config file.`
@ -111,7 +103,7 @@ func NewDefaultClient(airshipConfigPath *string) (*Client, error) {
}
// NewClient initializes the airshipctl client for external usage with the logging overridden.
func NewClient(airshipConfigPath, kubeConfigPath *string, request configs.WsMessage) (*Client, error) {
func NewClient(airshipConfigPath *string, request configs.WsMessage) (*Client, error) {
client, err := NewDefaultClient(airshipConfigPath)
if err != nil {
return nil, err

View File

@ -111,7 +111,7 @@ func getBaremetalDefaults(request configs.WsMessage) (baremetalData, error) {
// getNodeInfo gets and formats the default nodes as defined by the manifest(s)
func getNodeInfo(request configs.WsMessage) ([]nodeInfo, error) {
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
log.Error(err)
return nil, err
@ -198,7 +198,7 @@ func actionHelper(user *string, target string, phase string, request configs.WsM
// create a transaction for this singular request
transaction := statistics.NewTransaction(user, response)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, response)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, response)
if err != nil {
errorHelper(err, transaction, response)
return

View File

@ -52,8 +52,8 @@ func newResponse(request configs.WsMessage) configs.WsMessage {
}
}
// HandleConfigRequest will flop between requests so we don't have to have them all mapped as function calls
// This will wait for the sub component to complete before responding. The assumption is this is an async request
// HandleConfigRequest will find the appropriate subcomponent function in the function map
// and wait for it to complete before returning the response message
func HandleConfigRequest(user *string, request configs.WsMessage) configs.WsMessage {
var response configs.WsMessage
@ -71,7 +71,12 @@ func HandleConfigRequest(user *string, request configs.WsMessage) configs.WsMess
// GetAirshipConfigPath returns value stored in AirshipConfigPath
func GetAirshipConfigPath(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
response.Message = AirshipConfigPath
// leave message empty if the file doesn't exist
if configFileExists(configs.UIConfig.AirshipConfigPath) {
response.Message = configs.UIConfig.AirshipConfigPath
}
return response
}
@ -80,9 +85,15 @@ func GetAirshipConfigPath(request configs.WsMessage) configs.WsMessage {
func SetAirshipConfig(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
AirshipConfigPath = request.Message
configs.UIConfig.AirshipConfigPath = request.Message
err := configs.UIConfig.Persist()
if err != nil {
e := err.Error()
response.Error = &e
return response
}
msg := fmt.Sprintf("Config file set to '%s'", *AirshipConfigPath)
msg := fmt.Sprintf("Config file set to '%s'", *configs.UIConfig.AirshipConfigPath)
response.Message = &msg
return response
@ -92,7 +103,7 @@ func SetAirshipConfig(request configs.WsMessage) configs.WsMessage {
func GetCurrentContext(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -128,9 +139,16 @@ func InitAirshipConfig(request configs.WsMessage) configs.WsMessage {
return response
}
AirshipConfigPath = &confPath
configs.UIConfig.AirshipConfigPath = &confPath
// save this location back to airshipui config file so we'll remember it for next time
err = configs.UIConfig.Persist()
if err != nil {
e := err.Error()
response.Error = &e
return response
}
msg := fmt.Sprintf("Config file set to '%s'", *AirshipConfigPath)
msg := fmt.Sprintf("Config file set to '%s'", *configs.UIConfig.AirshipConfigPath)
response.Message = &msg
@ -148,7 +166,7 @@ type Context struct {
func GetContexts(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -184,7 +202,7 @@ type Manifest struct {
func GetManifests(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -216,7 +234,7 @@ type ManagementConfig struct {
func GetManagementConfigs(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -254,7 +272,7 @@ type EncryptionConfig struct {
func GetEncryptionConfigs(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -281,7 +299,7 @@ func GetEncryptionConfigs(request configs.WsMessage) configs.WsMessage {
func SetContext(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -327,7 +345,7 @@ func SetContext(request configs.WsMessage) configs.WsMessage {
func SetEncryptionConfig(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -376,7 +394,7 @@ func SetEncryptionConfig(request configs.WsMessage) configs.WsMessage {
func SetManagementConfig(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -420,7 +438,7 @@ func SetManagementConfig(request configs.WsMessage) configs.WsMessage {
func SetManifest(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -466,7 +484,7 @@ func SetManifest(request configs.WsMessage) configs.WsMessage {
func UseContext(request configs.WsMessage) configs.WsMessage {
response := newResponse(request)
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e

View File

@ -33,7 +33,7 @@ func HandleDocumentRequest(user *string, request configs.WsMessage) configs.WsMe
var err error
var message *string
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -62,7 +62,7 @@ func HandleDocumentRequest(user *string, request configs.WsMessage) configs.WsMe
func (c *Client) docPull() (*string, error) {
var message *string
cfgFactory := config.CreateFactory(AirshipConfigPath)
cfgFactory := config.CreateFactory(configs.UIConfig.AirshipConfigPath)
// 2nd arg is noCheckout, I assume we want to checkout the repo,
// so setting to false
err := pull.Pull(cfgFactory, false)

View File

@ -28,11 +28,8 @@ func TestHandleUnknownDocumentSubComponent(t *testing.T) {
SubComponent: "fake_subcomponent",
}
acp := "testdata/testairshipconfig"
kcp := "testdata/testkubeconfig"
AirshipConfigPath = &acp
KubeConfigPath = &kcp
path := "testdata/testairshipconfig"
configs.UIConfig.AirshipConfigPath = &path
user := "test"
response := HandleDocumentRequest(&user, request)

View File

@ -34,7 +34,7 @@ func HandleImageRequest(user *string, request configs.WsMessage) configs.WsMessa
var err error
var message *string
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e
@ -66,7 +66,7 @@ func HandleImageRequest(user *string, request configs.WsMessage) configs.WsMessa
// generate iso now just runs a phase and not an individual command
func (c *Client) generateIso() (*string, error) {
cfgFactory := config.CreateFactory(AirshipConfigPath)
cfgFactory := config.CreateFactory(configs.UIConfig.AirshipConfigPath)
p := &phase.RunCommand{
Factory: cfgFactory,
}

View File

@ -28,11 +28,8 @@ func TestHandleUnknownBaremetalSubComponent(t *testing.T) {
SubComponent: "fake_subcomponent",
}
acp := "testdata/testairshipconfig"
kcp := "testdata/testkubeconfig"
AirshipConfigPath = &acp
KubeConfigPath = &kcp
path := "testdata/testairshipconfig"
configs.UIConfig.AirshipConfigPath = &path
user := "test"
response := HandleBaremetalRequest(&user, request)

View File

@ -56,7 +56,7 @@ func HandlePhaseRequest(user *string, request configs.WsMessage) configs.WsMessa
var message *string
var valid bool
client, err := NewClient(AirshipConfigPath, KubeConfigPath, request)
client, err := NewClient(configs.UIConfig.AirshipConfigPath, request)
if err != nil {
e := err.Error()
response.Error = &e

View File

@ -26,6 +26,7 @@ import (
"github.com/google/uuid"
"opendev.org/airship/airshipctl/pkg/phase"
"opendev.org/airship/airshipctl/pkg/phase/ifc"
"opendev.org/airship/airshipui/pkg/configs"
"opendev.org/airship/airshipui/pkg/log"
"sigs.k8s.io/kustomize/api/types"
)
@ -38,7 +39,7 @@ func getHelper() (ifc.Helper, error) {
return helper, nil
}
c, err := NewDefaultClient(AirshipConfigPath)
c, err := NewDefaultClient(configs.UIConfig.AirshipConfigPath)
if err != nil {
return nil, err
}