package edgecli import ( "fmt" "log" "os" "strings" "gopkg.in/yaml.v2" ) type Config struct { CurrentBannerContext string `yaml:"currentBannerContext"` CurrentClusterContext string `yaml:"currentClusterContext"` BannerContexts map[string]*BannerContext `yaml:"bannerContexts"` ClusterContexts map[string]*ClusterContext `yaml:"clusterContexts"` } type BannerContext struct { BannerEdgeID string `yaml:"bannerEdgeID"` BannerName string `yaml:"bannerName"` TenantOrg string `yaml:"tenantOrg"` Username string `yaml:"username"` Endpoint string `yaml:"endpoint"` Token string `yaml:"token"` TokenTime string `yaml:"tokenTime"` } type ClusterContext struct { ClusterEdgeID string `yaml:"clusterEdgeID"` } const edgeDir = "/.edge" // ReadConfig reads from the .edge file to return an edgecli Config func ReadConfig() (*Config, error) { home, err := os.UserHomeDir() if err != nil { return &Config{}, err } // creating .edge file if it does not already exist edgeData, err := os.ReadFile(home + edgeDir) if err != nil { fmt.Println("Config file does not exist. Adding a .edge file to " + home) _, err = os.Create(home + edgeDir) if err != nil { return &Config{}, fmt.Errorf(".edge could not be created in %s: %w", home, err) } edgeData, err = os.ReadFile(home + edgeDir) if err != nil { return &Config{}, fmt.Errorf(".edge file could not be read: %w", err) } } var config Config err = yaml.Unmarshal(edgeData, &config) if err != nil { log.Fatal(err) } return &config, nil } // WriteConfig overwrites the .edge file with provided edgecli Config. func WriteConfig(cfg *Config) error { home, err := os.UserHomeDir() if err != nil { return err } // creating .edge file if it does not already exist _, err = os.ReadFile(home + edgeDir) if err != nil { fmt.Println("Config file does not exist. Adding a .edge file to " + home) _, err = os.Create(home + edgeDir) if err != nil { return fmt.Errorf(".edge could not be created in %s: %w", home, err) } } if err := os.Truncate(home+edgeDir, 0); err != nil { return err } data, err := yaml.Marshal(cfg) if err != nil { return fmt.Errorf("Could not marshall the config data: %w", err) } if err = os.WriteFile(home+edgeDir, data, 0644); err != nil { return fmt.Errorf("Could not write to edge file: %w", err) } return nil } func (cfg *Config) CurrentBanner() *BannerContext { banner := cfg.BannerContexts[cfg.CurrentBannerContext] if banner == nil { return &BannerContext{} } return banner } func (cfg *Config) CurrentCluster() *ClusterContext { cluster := cfg.ClusterContexts[cfg.CurrentClusterContext] if cluster == nil { return &ClusterContext{} } return cluster } // AddBanner adds new banner to config, returns it, and writes to .edge. func (cfg *Config) AddBanner(name, bannerEdgeID, bannerName, username, tenantOrg, endpoint, token, tokenTime string) (*BannerContext, error) { if cfg.BannerContexts == nil { cfg.BannerContexts = make(map[string]*BannerContext) } if bannerEdgeID == "" { return nil, fmt.Errorf("No Banner Edge ID provided") } if name == "" { return nil, fmt.Errorf("No banner context name provided") } if _, exists := cfg.BannerContexts[name]; exists { return nil, fmt.Errorf("Banner context named %s already exists", name) } cfg.BannerContexts[name] = &BannerContext{ BannerEdgeID: bannerEdgeID, BannerName: bannerName, Username: username, TenantOrg: tenantOrg, Endpoint: endpoint, Token: token, TokenTime: tokenTime, } // write config back to .edge file if err := WriteConfig(cfg); err != nil { return nil, err } return cfg.BannerContexts[name], nil } // AddCluster adds new cluster to config, returns it, and writes to .edge. func (cfg *Config) AddCluster(name, clusterEdgeID string) (*ClusterContext, error) { if cfg.ClusterContexts == nil { cfg.ClusterContexts = make(map[string]*ClusterContext) } if clusterEdgeID == "" { return nil, fmt.Errorf("No Cluster Edge ID provided") } if name == "" { name = clusterEdgeID } if _, exists := cfg.ClusterContexts[name]; exists { return nil, fmt.Errorf("Cluster context named %s already exists", name) } cfg.ClusterContexts[name] = &ClusterContext{ ClusterEdgeID: clusterEdgeID, } // write config back to .edge file if err := WriteConfig(cfg); err != nil { return nil, err } return cfg.ClusterContexts[name], nil } func (cfg *Config) UpdateBanner(name, bannerEdgeID, bannerName, username, tenantOrg, endpoint, token string) error { editingBanner, ok := cfg.BannerContexts[name] if !ok { return fmt.Errorf("Banner '%v' does not exist", name) } if bannerEdgeID != "" { editingBanner.BannerEdgeID = bannerEdgeID } if bannerName != "" { editingBanner.BannerName = bannerName } if username != "" { editingBanner.Username = username } if tenantOrg != "" { editingBanner.TenantOrg = tenantOrg } if endpoint != "" { editingBanner.Endpoint = endpoint } if token != "" { editingBanner.Token = token } return WriteConfig(cfg) } // UpdateCluster adds new cluster to config, returns it, and writes to .edge func (cfg *Config) UpdateCluster(name, clusterEdgeID string) error { editingCluster, ok := cfg.ClusterContexts[name] if !ok { return fmt.Errorf("Cluster '%v' does not exist", name) } if clusterEdgeID != "" { editingCluster.ClusterEdgeID = clusterEdgeID } return WriteConfig(cfg) } func (cfg *Config) SetBanner(name string) error { if _, ok := cfg.BannerContexts[name]; ok { cfg.CurrentBannerContext = name } else { return fmt.Errorf("Banner '%v' does not exist", name) } if err := WriteConfig(cfg); err != nil { return fmt.Errorf("Error writing to .edge file") } return nil } func (cfg *Config) SetCluster(name string) error { if _, ok := cfg.ClusterContexts[name]; ok { cfg.CurrentClusterContext = name } else { return fmt.Errorf("Cluster '%v' does not exist", name) } if err := WriteConfig(cfg); err != nil { return fmt.Errorf("Error writing to .edge file") } return nil } func (cfg *Config) DeleteBanner(name string) error { if _, ok := cfg.BannerContexts[name]; ok { if cfg.CurrentBannerContext == name { cfg.CurrentBannerContext = "" } delete(cfg.BannerContexts, name) } else { return fmt.Errorf("Banner '%v' does not exist", name) } return WriteConfig(cfg) } func (cfg *Config) DeleteCluster(name string) error { if _, ok := cfg.ClusterContexts[name]; ok { if cfg.CurrentClusterContext == name { cfg.CurrentClusterContext = "" } delete(cfg.ClusterContexts, name) } else { return fmt.Errorf("Cluster '%v' does not exist", name) } return WriteConfig(cfg) } func (cfg *Config) CurrentString() string { var b strings.Builder fmt.Fprint(&b, "CURRENT CONTEXT\n") fmt.Fprint(&b, " Banner: "+cfg.CurrentBannerContext+"\n") fmt.Fprint(&b, " Cluster: "+cfg.CurrentClusterContext+"\n") return b.String() } func (cfg *Config) BannerContextsString(verbose bool) string { var b strings.Builder fmt.Fprint(&b, "BANNER CONTEXTS\n") for bk := range cfg.BannerContexts { if verbose { fmt.Fprint(&b, "------\n") fmt.Fprint(&b, cfg.BannerString(bk)) } else { fmt.Fprintf(&b, " %s\n", bk) } } return b.String() } func (cfg *Config) ClusterContextsString(verbose bool) string { var b strings.Builder fmt.Fprint(&b, "CLUSTER CONTEXTS\n") for ck := range cfg.ClusterContexts { if verbose { fmt.Fprint(&b, "------\n") fmt.Fprint(&b, cfg.ClusterString(ck)) } else { fmt.Fprintf(&b, " %s\n", ck) } } return b.String() } func (cfg *Config) BannerString(name string) string { banner, exists := cfg.BannerContexts[name] if !exists { return "" } var b strings.Builder fmt.Fprintf(&b, " Name: %s\n", name) if banner.BannerEdgeID != "" { fmt.Fprintf(&b, " EdgeId: %s\n", banner.BannerEdgeID) } if banner.TenantOrg != "" { fmt.Fprintf(&b, " Tenant Org: %s\n", banner.TenantOrg) } if banner.Username != "" { fmt.Fprintf(&b, " Username: %s\n", banner.Username) } if banner.Token != "" { fmt.Fprintf(&b, " Token: %s\n", banner.Token) } if banner.TokenTime != "" { fmt.Fprintf(&b, " Token Time: %s\n", banner.TokenTime) } return b.String() } func (cfg *Config) ClusterString(name string) string { cluster, exists := cfg.ClusterContexts[name] if !exists { return "" } var b strings.Builder fmt.Fprintf(&b, " Name: %s\n", name) fmt.Fprintf(&b, " EdgeId: %s\n", cluster.ClusterEdgeID) return b.String() }