Skip to content

Commit

Permalink
config cmd
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasparada committed Dec 3, 2021
1 parent 886d9b9 commit 4eac16c
Show file tree
Hide file tree
Showing 9 changed files with 218 additions and 24 deletions.
18 changes: 18 additions & 0 deletions cmd/calyptia/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package main

import "github.com/spf13/cobra"

func newCmdConfig(config *config) *cobra.Command {
cmd := &cobra.Command{
Use: "config",
Short: "Configure Calyptia CLI",
}

cmd.AddCommand(
newCmdConfigSetProject(config),
newCmdConfigCurrentProject(config),
newCmdConfigUnsetProject(config),
)

return cmd
}
136 changes: 136 additions & 0 deletions cmd/calyptia/config_project.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package main

import (
"errors"
"fmt"
"io/fs"
"os"
"path/filepath"
"strings"

"github.com/spf13/cobra"
)

func newCmdConfigSetProject(config *config) *cobra.Command {
return &cobra.Command{
Use: "set_project PROJECT",
Short: "Set the default project so you don't have to specify it on all commands",
Args: cobra.ExactArgs(1),
ValidArgsFunction: config.completeProjects,
RunE: func(cmd *cobra.Command, args []string) error {
projectKey := args[0]
projectID := projectKey
{
pp, err := config.cloud.Projects(config.ctx, 0)
if err != nil {
return err
}

a, ok := findProjectByName(pp, projectKey)
if !ok && !validUUID(projectID) {
return fmt.Errorf("could not find project %q", projectKey)
}

if ok {
projectID = a.ID
}
}

if err := saveDefaultProject(projectID); err != nil {
return err
}

config.defaultProject = projectID

return nil
},
}
}

func newCmdConfigCurrentProject(config *config) *cobra.Command {
return &cobra.Command{
Use: "current_project",
Short: "Get the current configured default project",
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Println(config.defaultProject)
return nil
},
}
}

func newCmdConfigUnsetProject(config *config) *cobra.Command {
return &cobra.Command{
Use: "unset_project",
Short: "Unset the current configured default project",
RunE: func(cmd *cobra.Command, args []string) error {
if err := deleteSavedDefaultProject(); err != nil {
return err
}

config.defaultProject = ""
return nil
},
}
}

func saveDefaultProject(projectKey string) error {
home, err := os.UserHomeDir()
if err != nil {
return err
}

fileName := filepath.Join(home, ".calyptia", "default_project")
if _, err := os.Stat(fileName); os.IsNotExist(err) {
err = os.MkdirAll(filepath.Dir(fileName), fs.ModePerm)
if err != nil {
return fmt.Errorf("could not create directory: %w", err)
}
}

err = os.WriteFile(fileName, []byte(projectKey), fs.ModePerm)
if err != nil {
return fmt.Errorf("could not store default project: %w", err)
}

return nil
}

var errDefaultProjectNotFound = errors.New("default project not found")

func savedDefaultProject() (string, error) {
home, err := os.UserHomeDir()
if err != nil {
return "", fmt.Errorf("could not get user home dir: %w", err)
}

b, err := readFile(filepath.Join(home, ".calyptia", "default_project"))
if os.IsNotExist(err) || errors.Is(err, fs.ErrNotExist) {
return "", errDefaultProjectNotFound
}

if err != nil {
return "", err
}

projectKey := strings.TrimSpace(string(b))
return projectKey, nil
}

func deleteSavedDefaultProject() error {
home, err := os.UserHomeDir()
if err != nil {
return err
}

fileName := filepath.Join(home, ".calyptia", "default_project")
if _, err := os.Stat(fileName); os.IsNotExist(err) {
return nil
}

err = os.Remove(fileName)
if err != nil {
return fmt.Errorf("could not delete default project: %w", err)
}

return nil
}
9 changes: 6 additions & 3 deletions cmd/calyptia/create_aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"encoding/json"
"errors"
"fmt"
"os"

Expand All @@ -19,6 +20,10 @@ func newCmdCreateAggregator(config *config) *cobra.Command {
Use: "aggregator",
Short: "Create a new aggregator",
RunE: func(cmd *cobra.Command, args []string) error {
if projectKey == "" {
return errors.New("project required")
}

projectID := projectKey
{
pp, err := config.cloud.Projects(config.ctx, 0)
Expand Down Expand Up @@ -66,14 +71,12 @@ func newCmdCreateAggregator(config *config) *cobra.Command {
}

fs := cmd.Flags()
fs.StringVar(&projectKey, "project", "", "Parent project ID or name")
fs.StringVar(&projectKey, "project", config.defaultProject, "Parent project ID or name")
fs.StringVar(&name, "name", "", "Aggregator name; leave it empty to generate a random name")
fs.StringVarP(&format, "output-format", "f", "table", "Output format. Allowed: table, json")

_ = cmd.RegisterFlagCompletionFunc("project", config.completeProjects)
_ = cmd.RegisterFlagCompletionFunc("output-format", config.completeOutputFormat)

_ = cmd.MarkFlagRequired("project") // TODO: use default project ID from config cmd.

return cmd
}
9 changes: 6 additions & 3 deletions cmd/calyptia/delete_agent.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package main

import (
"errors"
"fmt"
"strings"
"time"
Expand Down Expand Up @@ -79,6 +80,10 @@ func newCmdDeleteAgents(config *config) *cobra.Command {
Use: "agents",
Short: "Delete many agents from a project",
RunE: func(cmd *cobra.Command, args []string) error {
if projectKey == "" {
return errors.New("project required")
}

projectID := projectKey
{
pp, err := config.cloud.Projects(config.ctx, 0)
Expand Down Expand Up @@ -156,13 +161,11 @@ func newCmdDeleteAgents(config *config) *cobra.Command {
}

fs := cmd.Flags()
fs.StringVar(&projectKey, "project", "", "Delete agents from this project ID or name")
fs.StringVar(&projectKey, "project", config.defaultProject, "Delete agents from this project ID or name")
fs.BoolVar(&inactive, "inactive", true, "Delete inactive agents only")
fs.BoolVarP(&confirmed, "yes", "y", false, "Confirm deletion")

_ = cmd.RegisterFlagCompletionFunc("project", config.completeProjects)

_ = cmd.MarkFlagRequired("project") // TODO: use default project ID from config cmd.

return cmd
}
13 changes: 8 additions & 5 deletions cmd/calyptia/get_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"encoding/json"
"errors"
"fmt"
"os"
"sync"
Expand All @@ -18,13 +19,17 @@ import (
)

func newCmdGetAgents(config *config) *cobra.Command {
var format string
var projectKey string
var last uint64
var format string
cmd := &cobra.Command{
Use: "agents",
Short: "Display latest agents from a project",
RunE: func(cmd *cobra.Command, args []string) error {
if projectKey == "" {
return errors.New("project required")
}

projectID := projectKey
{
pp, err := config.cloud.Projects(config.ctx, 0)
Expand Down Expand Up @@ -73,15 +78,13 @@ func newCmdGetAgents(config *config) *cobra.Command {
}

fs := cmd.Flags()
fs.StringVarP(&format, "output-format", "o", "table", "Output format. Allowed: table, json")
fs.StringVar(&projectKey, "project", "", "Parent project ID or name")
fs.StringVar(&projectKey, "project", config.defaultProject, "Parent project ID or name")
fs.Uint64VarP(&last, "last", "l", 0, "Last `N` agents. 0 means no limit")
fs.StringVarP(&format, "output-format", "o", "table", "Output format. Allowed: table, json")

_ = cmd.RegisterFlagCompletionFunc("output-format", config.completeOutputFormat)
_ = cmd.RegisterFlagCompletionFunc("project", config.completeProjects)

_ = cmd.MarkFlagRequired("project") // TODO: use default project ID from config cmd.

return cmd
}

Expand Down
9 changes: 6 additions & 3 deletions cmd/calyptia/get_aggregator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"encoding/json"
"errors"
"fmt"
"os"
"sync"
Expand All @@ -21,6 +22,10 @@ func newCmdGetAggregators(config *config) *cobra.Command {
Use: "aggregators",
Short: "Display latest aggregators from a project",
RunE: func(cmd *cobra.Command, args []string) error {
if projectKey == "" {
return errors.New("project required")
}

projectID := projectKey
{
pp, err := config.cloud.Projects(config.ctx, 0)
Expand Down Expand Up @@ -70,14 +75,12 @@ func newCmdGetAggregators(config *config) *cobra.Command {

fs := cmd.Flags()
fs.StringVarP(&format, "output-format", "o", "table", "Output format. Allowed: table, json")
fs.StringVar(&projectKey, "project", "", "Parent project ID or name")
fs.StringVar(&projectKey, "project", config.defaultProject, "Parent project ID or name")
fs.Uint64VarP(&last, "last", "l", 0, "Last `N` aggregators. 0 means no limit")

_ = cmd.RegisterFlagCompletionFunc("output-format", config.completeOutputFormat)
_ = cmd.RegisterFlagCompletionFunc("project", config.completeProjects)

_ = cmd.MarkFlagRequired("project") // TODO: use default project ID from config cmd.

return cmd
}

Expand Down
19 changes: 16 additions & 3 deletions cmd/calyptia/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,17 @@ func newCmd(ctx context.Context) *cobra.Command {

// Now all requests will be authenticated and the token refreshes by its own.
config.cloud.HTTPClient = config.auth0.Client(config.ctx, tok)
}, func() {
if config.defaultProject != "" {
return
}

projectKey, err := savedDefaultProject()
if err == errDefaultProjectNotFound {
return
}

config.defaultProject = projectKey
})
cmd := &cobra.Command{
Use: "calyptia",
Expand All @@ -82,6 +93,7 @@ func newCmd(ctx context.Context) *cobra.Command {

cmd.AddCommand(
newCmdLogin(config),
newCmdConfig(config),
newCmdCreate(config),
newCmdGet(config),
newCmdUpdate(config),
Expand All @@ -93,9 +105,10 @@ func newCmd(ctx context.Context) *cobra.Command {
}

type config struct {
ctx context.Context
auth0 *auth0.Client
cloud *cloudclient.Client
ctx context.Context
auth0 *auth0.Client
cloud *cloudclient.Client
defaultProject string
}

func env(key, fallback string) string {
Expand Down
15 changes: 11 additions & 4 deletions cmd/calyptia/top_project.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"context"
"errors"
"fmt"
"io"
"math"
Expand Down Expand Up @@ -40,13 +41,19 @@ func newCmdTopProject(config *config) *cobra.Command {
var start, interval time.Duration
var last uint64
cmd := &cobra.Command{
Use: "project PROJECT",
Use: "project [PROJECT]",
Short: "Display metrics from a project",
Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
ValidArgsFunction: config.completeProjects,
// TODO: run an interactive "top" program.
RunE: func(cmd *cobra.Command, args []string) error {
projectKey := args[0]
projectKey := config.defaultProject
if len(args) > 0 {
projectKey = args[0]
}
if projectKey == "" {
return errors.New("project required")
}

initialModel := &Model{
StartingProjectKey: projectKey,
ProjectModel: NewProjectModel(config.ctx, config.cloud, projectKey, start, interval, last),
Expand Down
Loading

0 comments on commit 4eac16c

Please sign in to comment.