Skip to content

Commit

Permalink
improving local config (hack, do not merge)
Browse files Browse the repository at this point in the history
  • Loading branch information
sebv committed Nov 20, 2023
1 parent 1f5fa8b commit b6aab8b
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 10 deletions.
58 changes: 58 additions & 0 deletions internal/clientconfig/clientconfig.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
package clientconfig

import (
"os"
"path/filepath"

"github.com/saucelabs/saucectl/internal/iam"
"gopkg.in/yaml.v2"
)

// just breaking the dependendency cycle, must be better ways
type RegionConf struct {
Name string `yaml:"name"`
APIBaseURL string `yaml:"apiBaseURL,omitempty"`
AppBaseURL string `yaml:"appBaseURL,omitempty"`
WebDriverBaseURL string `yaml:"webdriverBaseURL,omitempty"`
}

type ClientConfig struct {
Regions []RegionConf `yaml:"regions,omitempty"`
Credentials map[string]iam.Credentials `yaml:"credentials,omitempty"`
}

func FromFile(path string) (*ClientConfig, error) {
// read the contents of the YAML file
data, err := os.ReadFile(path)
if err != nil {
return nil, err
}

// unmarshal the YAML data into a struct
var config ClientConfig
err = yaml.Unmarshal(data, &config)
if err != nil {
return nil, err
}
return &config, nil
}

var config *ClientConfig

func Get() (*ClientConfig, error) {
if config != nil {
return config, nil
}
homeDir, _ := os.UserHomeDir()
configPath := filepath.Join(homeDir, ".sauce", "saucectl.yaml")
// if file config file does not exist, return nil
if _, err := os.Stat(configPath); os.IsNotExist(err) {
return nil, nil
}
_config, err := FromFile(configPath)
if err != nil {
return nil, err
}
config = _config
return config, nil
}
2 changes: 1 addition & 1 deletion internal/cmd/imagerunner/cmd.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ func Command(preRun func(cmd *cobra.Command, args []string)) *cobra.Command {
segment.DefaultTracker.Enabled = false
}

creds := credentials.Get()
creds := credentials.GetV2(region.FromString(regio))
url := region.FromString(regio).APIBaseURL()

imagerunnerClient = http.NewImageRunner(url, creds, 15*time.Minute)
Expand Down
3 changes: 2 additions & 1 deletion internal/cmd/run/imagerunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ func runImageRunner(cmd *cobra.Command) (int, error) {
}

regio := region.FromString(p.Sauce.Region)

tracker := segment.DefaultTracker
if regio == region.Staging {
tracker.Enabled = false
Expand Down Expand Up @@ -66,7 +67,7 @@ func runImageRunner(cmd *cobra.Command) (int, error) {

cleanupArtifacts(p.Artifacts)

creds := credentials.Get()
creds := credentials.GetV2(regio)
imageRunnerClient := http.NewImageRunner(regio.APIBaseURL(), creds, imgExecTimeout)
restoClient := http.NewResto(regio.APIBaseURL(), creds.Username, creds.AccessKey, 0)

Expand Down
29 changes: 29 additions & 0 deletions internal/credentials/credentials.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ import (
"path/filepath"

"github.com/rs/zerolog/log"
"github.com/saucelabs/saucectl/internal/clientconfig"
"github.com/saucelabs/saucectl/internal/iam"
"github.com/saucelabs/saucectl/internal/region"
"github.com/saucelabs/saucectl/internal/yaml"
yamlbase "gopkg.in/yaml.v2"
)
Expand Down Expand Up @@ -36,7 +38,34 @@ func Get() iam.Credentials {
if c := FromEnv(); c.IsSet() {
return c
}
/*clientConf, err := clientconfig.Get()
if err != nil {
log.Warn().Err(err).Msg("failed to read client config")
}
*/
return FromFile()
}

// Get returns the configured credentials.
// Effectively a convenience wrapper around FromEnv, followed by a call to FromFile.
//
// The lookup order is:
// 1. Environment variables (see FromEnv)
// 2. Per region Credentials
// 3. Credentials file (see FromFile)
func GetV2(region region.Region) iam.Credentials {
if c := FromEnv(); c.IsSet() {
return c
}
clientConf, err := clientconfig.Get()
if err != nil {
log.Warn().Err(err).Msg("failed to read client config")
}
if clientConf != nil {
if creds, ok := clientConf.Credentials[region.String()]; ok {
return creds
}
}
return FromFile()
}

Expand Down
1 change: 0 additions & 1 deletion internal/http/imagerunner.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ func (c *ImageRunner) TriggerRun(ctx context.Context, spec imagerunner.RunnerSpe
if err != nil {
return runner, err
}

req.SetBasicAuth(c.Creds.Username, c.Creds.AccessKey)
req.Header.Set("Content-Type", "application/json")

Expand Down
64 changes: 57 additions & 7 deletions internal/region/region.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
package region

import (
"github.com/rs/zerolog/log"
"github.com/saucelabs/saucectl/internal/clientconfig"
)

// Region represents the sauce labs region.
type Region uint

Expand All @@ -16,12 +21,14 @@ const (
Staging
)

var meta = []struct {
Name string
APIBaseURL string
AppBaseURL string
WebDriverBaseURL string
}{
type Data struct {
Name string `json:"name"`
APIBaseURL string `json:"apiBaseURL,omitempty"`
AppBaseURL string `json:"appBaseURL,omitempty"`
WebDriverBaseURL string `json:"webdriverBaseURL,omitempty"`
}

var meta = []Data{
// None
{
"",
Expand Down Expand Up @@ -59,19 +66,62 @@ var meta = []struct {
},
}

var initialized = false

func Init() {
if initialized {
return
}
clientConf, err := clientconfig.Get()
if err != nil {
log.Warn().Err(err).Msg("failed to read client config")
return
}
if clientConf != nil {
for _, r := range clientConf.Regions {
found := false
for i, m := range meta {
if m.Name == r.Name {
found = true
if r.APIBaseURL != "" {
meta[i].APIBaseURL = r.APIBaseURL
}
if r.AppBaseURL != "" {
meta[i].AppBaseURL = r.AppBaseURL
}
if r.WebDriverBaseURL != "" {
meta[i].WebDriverBaseURL = r.WebDriverBaseURL
}
break
}
}
if !found {
meta = append(meta, Data{
Name: r.Name,
APIBaseURL: r.APIBaseURL,
AppBaseURL: r.AppBaseURL,
WebDriverBaseURL: r.WebDriverBaseURL,
})
}
}
}
initialized = true
}

func (r Region) String() string {
Init()
return meta[r].Name
}

// FromString converts the given string to the corresponding Region.
// Returns None if the string did not match any Region.
func FromString(s string) Region {
Init()
for i, m := range meta {
if m.Name == s {
return Region(i)
}
}

return None
}

Expand Down

0 comments on commit b6aab8b

Please sign in to comment.