Skip to content

Commit

Permalink
Improve error handling and authentication error messages
Browse files Browse the repository at this point in the history
  • Loading branch information
kajogo777 committed May 7, 2023
1 parent 7703edf commit 8e9055f
Show file tree
Hide file tree
Showing 10 changed files with 150 additions and 35 deletions.
22 changes: 22 additions & 0 deletions cmd/devx/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,25 @@ var loginCmd = &cobra.Command{
return nil
},
}

var clearCmd = &cobra.Command{
Use: "clear",
Short: "Clear cached credentials",
RunE: func(cmd *cobra.Command, args []string) error {
if err := auth.Clear(server); err != nil {
return err
}
return nil
},
}

var infoCmd = &cobra.Command{
Use: "info",
Short: "Display session information",
RunE: func(cmd *cobra.Command, args []string) error {
if err := auth.Info(server); err != nil {
return err
}
return nil
},
}
2 changes: 1 addition & 1 deletion cmd/devx/build.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ var buildCmd = &cobra.Command{
Args: cobra.ExactArgs(1),
Aliases: []string{"do"},
RunE: func(cmd *cobra.Command, args []string) error {
if err := client.Run(args[0], configDir, stackPath, buildersPath, reserve, dryRun, server, strict, stdout); err != nil {
if err := client.Run(args[0], configDir, stackPath, buildersPath, reserve, dryRun, server, noStrict, stdout); err != nil {
return fmt.Errorf(errors.Details(err, nil))
}
return nil
Expand Down
2 changes: 1 addition & 1 deletion cmd/devx/diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ var diffCmd = &cobra.Command{
Short: "Diff the current stack with that @ target (e.g. HEAD, commit, tag).",
Args: cobra.ExactArgs(2),
RunE: func(cmd *cobra.Command, args []string) error {
if err := client.Diff(args[0], args[1], configDir, stackPath, buildersPath, server, strict); err != nil {
if err := client.Diff(args[0], args[1], configDir, stackPath, buildersPath, server, noStrict); err != nil {
return fmt.Errorf(errors.Details(err, nil))
}
return nil
Expand Down
35 changes: 32 additions & 3 deletions cmd/devx/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,12 @@ package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
"strings"

"github.com/devopzilla/guku-devx/pkg/auth"
log "github.com/sirupsen/logrus"
"github.com/spf13/cobra"
)

Expand All @@ -18,7 +21,7 @@ var (
showTransformers bool
dryRun bool
noColor bool
strict bool
noStrict bool
verbosity string
stdout bool
reserve bool
Expand All @@ -44,7 +47,7 @@ func init() {
rootCmd.PersistentFlags().StringVarP(&stackPath, "stack", "s", "stack", "stack field name in config file")
rootCmd.PersistentFlags().StringVarP(&buildersPath, "builders", "b", "builders", "builders field name in config file")
rootCmd.PersistentFlags().BoolVar(&noColor, "no-color", false, "disable colors")
rootCmd.PersistentFlags().BoolVarP(&strict, "strict", "S", false, "make sure all traits are fulfilled by at least one flow")
rootCmd.PersistentFlags().BoolVarP(&noStrict, "no-strict", "S", false, "ignore traits not fulfilled by a builder")
buildCmd.PersistentFlags().BoolVarP(&reserve, "reserve", "r", false, "reserve build resources")
buildCmd.PersistentFlags().BoolVarP(&dryRun, "dry-run", "d", false, "output the entire stack after transformation without applying drivers")
buildCmd.PersistentFlags().BoolVarP(&stdout, "stdout", "o", false, "output result to stdout")
Expand Down Expand Up @@ -95,13 +98,18 @@ func init() {
publishCatalogCmd,
publishModuleCmd,
)

loginCmd.AddCommand(
clearCmd,
infoCmd,
)
}

var rootCmd = &cobra.Command{
Use: "devx",
Short: "guku DevX cloud native self-service magic",
SilenceUsage: true,
PersistentPreRun: setupLogging,
PersistentPreRun: preRun,
}

var versionCmd = &cobra.Command{
Expand All @@ -120,6 +128,27 @@ var versionCmd = &cobra.Command{
},
}

func preRun(cmd *cobra.Command, args []string) {
setupLogging(cmd, args)

resp, err := http.Get("https://api.github.com/repos/devopzilla/guku-devx/releases?per_page=1")
if err == nil {
releases := []struct {
TagName string `json:"tag_name"`
}{}

json.NewDecoder(resp.Body).Decode(&releases)

if len(releases) > 0 {
latestVersion := strings.TrimPrefix(releases[0].TagName, "v")
if latestVersion != version && version != "DEV" {
log.Infof("A newer version of DevX \"v%s\" is available, please upgrade!\n", latestVersion)
}
}

}
}

func main() {
if err := rootCmd.Execute(); err != nil {
os.Exit(1)
Expand Down
2 changes: 1 addition & 1 deletion cmd/devx/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ var validateCmd = &cobra.Command{
Aliases: []string{"v"},
Short: "Validate configurations",
RunE: func(cmd *cobra.Command, args []string) error {
if err := project.Validate(configDir, stackPath, buildersPath, strict); err != nil {
if err := project.Validate(configDir, stackPath, buildersPath, noStrict); err != nil {
return fmt.Errorf(errors.Details(err, nil))
}
return nil
Expand Down
63 changes: 61 additions & 2 deletions pkg/auth/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,50 @@ func GetDefaultToken() (string, *string, error) {
return tenant, cfg.Token, nil
}

func Clear(server ServerConfig) error {
return deleteConfig()
}

func Info(server ServerConfig) error {
var cfg Config

if server.Tenant == "" {
tenant, _, err := loadDefaultConfig()
if err != nil {
return err
}
server.Tenant = tenant
}

cfgFile, err := loadConfig()
if err != nil {
return err
}

if _, ok := cfgFile[server.Tenant]; ok {
cfg = cfgFile[server.Tenant]
}

log.Infof(`Auth info:
Tenant: %s
Server endpoint: %s
Token valid until: %s
`,
server.Tenant,
*cfg.Endpoint,
cfg.TokenExpiresOn,
)

return nil
}

func Login(server ServerConfig) error {
if server.Endpoint == "" {
server.Endpoint = DEVX_CLOUD_ENDPOINT
}

if server.Tenant == "" {
return fmt.Errorf("--tenant is required")
return fmt.Errorf("--tenant <tenant name> is required")
}

cfgFile, err := loadConfig()
Expand Down Expand Up @@ -212,7 +249,7 @@ func loadDefaultConfig() (string, Config, error) {
return tenant, cfg, nil
}
}
return "", Config{}, fmt.Errorf("no configs found. login and try again")
return "", Config{}, fmt.Errorf("no credentials found\nTry logging in using\n\ndevx login --tenant <your tenant>")
}

func loadConfig() (ConfigFile, error) {
Expand Down Expand Up @@ -261,3 +298,25 @@ func saveConfig(cfg ConfigFile) error {

return os.WriteFile(configPath, configData, 0700)
}

func deleteConfig() error {
configDir, err := getConfigDir()
if err != nil {
return err
}

if _, err := os.Stat(configDir); os.IsNotExist(err) {
err = os.MkdirAll(configDir, 0700)
if err != nil {
return err
}
}

configPath := filepath.Join(configDir, "config")

if err := os.Remove(configPath); err != nil {
return err
}

return nil
}
2 changes: 1 addition & 1 deletion pkg/catalog/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type ModuleCUE struct {
func PublishModule(gitDir string, configDir string, server auth.ServerConfig, tags []string) error {
gitData, err := gitrepo.GetGitData(gitDir)
if err != nil {
return nil
return err
}

tagsToPush := []string{}
Expand Down
14 changes: 7 additions & 7 deletions pkg/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ import (
"github.com/devopzilla/guku-devx/pkg/utils"
)

func Run(environment string, configDir string, stackPath string, buildersPath string, reserve bool, dryRun bool, server auth.ServerConfig, strict bool, stdout bool) error {
func Run(environment string, configDir string, stackPath string, buildersPath string, reserve bool, dryRun bool, server auth.ServerConfig, noStrict bool, stdout bool) error {
ctx := context.Background()
ctx = context.WithValue(ctx, utils.ConfigDirKey, configDir)
ctx = context.WithValue(ctx, utils.DryRunKey, dryRun)

stack, builder, err := buildStack(ctx, environment, configDir, stackPath, buildersPath, strict)
stack, builder, err := buildStack(ctx, environment, configDir, stackPath, buildersPath, noStrict)
if err != nil {
return err
}
Expand Down Expand Up @@ -63,7 +63,7 @@ func Run(environment string, configDir string, stackPath string, buildersPath st
return nil
}

func Diff(target string, environment string, configDir string, stackPath string, buildersPath string, server auth.ServerConfig, strict bool) error {
func Diff(target string, environment string, configDir string, stackPath string, buildersPath string, server auth.ServerConfig, noStrict bool) error {
log.Infof("📍 Processing target stack @ %s", target)
targetDir, err := os.MkdirTemp("", "devx-target-*")
if err != nil {
Expand Down Expand Up @@ -103,7 +103,7 @@ func Diff(target string, environment string, configDir string, stackPath string,
targetCtx := context.Background()
targetCtx = context.WithValue(targetCtx, utils.ConfigDirKey, targetDir)
targetCtx = context.WithValue(targetCtx, utils.DryRunKey, true)
targetStack, _, err := buildStack(targetCtx, environment, targetDir, stackPath, buildersPath, strict)
targetStack, _, err := buildStack(targetCtx, environment, targetDir, stackPath, buildersPath, noStrict)
if err != nil {
return err
}
Expand All @@ -112,7 +112,7 @@ func Diff(target string, environment string, configDir string, stackPath string,
currentCtx := context.Background()
currentCtx = context.WithValue(currentCtx, utils.ConfigDirKey, configDir)
currentCtx = context.WithValue(currentCtx, utils.DryRunKey, true)
currentStack, _, err := buildStack(currentCtx, environment, configDir, stackPath, buildersPath, strict)
currentStack, _, err := buildStack(currentCtx, environment, configDir, stackPath, buildersPath, noStrict)
if err != nil {
return err
}
Expand Down Expand Up @@ -160,7 +160,7 @@ func Diff(target string, environment string, configDir string, stackPath string,
return nil
}

func buildStack(ctx context.Context, environment string, configDir string, stackPath string, buildersPath string, strict bool) (*stack.Stack, *stackbuilder.StackBuilder, error) {
func buildStack(ctx context.Context, environment string, configDir string, stackPath string, buildersPath string, noStrict bool) (*stack.Stack, *stackbuilder.StackBuilder, error) {
log.Infof("🏗️ Loading stack...")
overlays, err := utils.GetOverlays(configDir)
if err != nil {
Expand All @@ -169,7 +169,7 @@ func buildStack(ctx context.Context, environment string, configDir string, stack
value, stackId, depIds := utils.LoadProject(configDir, &overlays)

log.Info("👀 Validating stack...")
err = project.ValidateProject(value, stackPath, buildersPath, strict)
err = project.ValidateProject(value, stackPath, buildersPath, noStrict)
if err != nil {
return nil, nil, err
}
Expand Down
31 changes: 14 additions & 17 deletions pkg/project/project.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,22 @@ import (

const stakpakPrefix = "stakpak://"

func Validate(configDir string, stackPath string, buildersPath string, strict bool) error {
func Validate(configDir string, stackPath string, buildersPath string, noStrict bool) error {
overlays, err := utils.GetOverlays(configDir)
if err != nil {
return err
}

value, _, _ := utils.LoadProject(configDir, &overlays)
if err := ValidateProject(value, stackPath, buildersPath, strict); err != nil {
if err := ValidateProject(value, stackPath, buildersPath, noStrict); err != nil {
return err
}

log.Info("👌 All looks good")
return nil
}

func ValidateProject(value cue.Value, stackPath string, buildersPath string, strict bool) error {
func ValidateProject(value cue.Value, stackPath string, buildersPath string, noStrict bool) error {
err := value.Validate()
if err != nil {
return err
Expand Down Expand Up @@ -77,24 +77,21 @@ func ValidateProject(value cue.Value, stackPath string, buildersPath string, str
return err
}

if strict {
builders, err := stackbuilder.NewEnvironments(value.LookupPath(cue.ParsePath(buildersPath)))
if err != nil {
return err
}
if noStrict {
return nil
}

stack, err := stack.NewStack(stackValue, "", []string{})
if err != nil {
return err
}
builders, err := stackbuilder.NewEnvironments(value.LookupPath(cue.ParsePath(buildersPath)))
if err != nil {
return err
}

err = stackbuilder.CheckTraitFulfillment(builders, stack)
if err != nil {
return err
}
stack, err := stack.NewStack(stackValue, "", []string{})
if err != nil {
return err
}

return nil
return stackbuilder.CheckTraitFulfillment(builders, stack)
}

func Discover(configDir string, showDefs bool, showTransformers bool) error {
Expand Down
12 changes: 10 additions & 2 deletions pkg/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -393,7 +393,11 @@ func SendData(server auth.ServerConfig, apiPath string, data interface{}) ([]byt
log.Fatalf("failed to parse error response body: %s", body)
}

return body, errors.New(errResponse.Message)
if response.StatusCode == 401 {
return nil, fmt.Errorf("authentication failed with error message: %s\nTry logging in using\n\ndevx login --tenant <your tenant>", errResponse.Message)
}

return nil, errors.New(errResponse.Message)
}

return body, nil
Expand Down Expand Up @@ -451,7 +455,11 @@ func GetData(server auth.ServerConfig, apiPath string, id *string, query map[str
log.Fatalf("failed to parse error response body: %s", body)
}

return body, errors.New(errResponse.Message)
if response.StatusCode == 401 {
return nil, fmt.Errorf("authentication failed with error message: %s\nTry logging in using\n\ndevx login --tenant <your tenant>", errResponse.Message)
}

return nil, errors.New(errResponse.Message)
}

return body, nil
Expand Down

0 comments on commit 8e9055f

Please sign in to comment.