Skip to content

Commit

Permalink
feat: [wip] prototype to support yaml file as input for synthetics mo…
Browse files Browse the repository at this point in the history
…nitor run command
  • Loading branch information
sanderblue committed Jun 28, 2023
1 parent 5238b16 commit bfd4c0e
Show file tree
Hide file tree
Showing 6 changed files with 155 additions and 36 deletions.
16 changes: 13 additions & 3 deletions internal/synthetics/command_monitor.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@ import (
)

var (
statusFilter string
monitorName string
monitorID string
statusFilter string
monitorName string
monitorID string
syntheticsMonitorGUID string
syntheticsMonitorLocationID string
syntheticsMonitorRunFlagsInputFile string
)

// Command represents the synthetics command
Expand Down Expand Up @@ -181,4 +184,11 @@ func init() {

cmdMonSearch.Flags().StringVarP(&monitorName, "name", "n", "", "search for results matching the given Synthetics monitor name")
cmdMon.AddCommand(cmdMonSearch)

cmdMonitorRun.Flags().StringVarP(&syntheticsMonitorGUID, "guid", "g", "", "The monitor GUID for which to run the monitor check.")
cmdMonitorRun.Flags().StringVarP(&syntheticsMonitorLocationID, "locationId", "l", "", "The monitor location ID for which to run the monitor check.")
cmdMonitorRun.MarkFlagRequired("guid")
cmdMonitorRun.MarkFlagRequired("locationId")
cmdMon.AddCommand(cmdMonitorRun)

}
65 changes: 65 additions & 0 deletions internal/synthetics/command_monitor_run.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package synthetics

import (
"encoding/json"
"fmt"
"io/ioutil"

"github.com/newrelic/newrelic-cli/internal/client"
"github.com/newrelic/newrelic-cli/internal/utils"
"github.com/spf13/cobra"
"gopkg.in/yaml.v2"
)

type commandInputs struct {
Flags map[string]interface{} `yaml:"flags"`
}

var cmdMonitorRun = &cobra.Command{
Use: "run",
Short: "Run a synthetics monitor check.",
Long: `Run a synthetics monitor check.
The get command queues a manual request to execute a monitor check from the specified location.
`,
Example: `newrelic synthetics monitor run --guid "<monitorGUID>" --location="<locationId>"`,
PreRun: client.RequireClient,
PreRunE: func(cmd *cobra.Command, args []string) error {

// TODO
// If command flags are provided inline as well as an input file for flags,
// the inline flags will take precendence and the input file flags will be ignored.
// Provide a warning message, but return nil and continue command execution in Run().

if syntheticsMonitorGUID != "" || syntheticsMonitorLocationID != "" {
return nil
}

inputFile, err := ioutil.ReadFile(syntheticsMonitorRunFlagsInputFile)
if err != nil {
return fmt.Errorf("YAML err %+v ", err)
}

cmdInputs := commandInputs{}
err = yaml.Unmarshal(inputFile, &cmdInputs)
if err != nil {
err = json.Unmarshal(inputFile, &cmdInputs)
if err != nil {
return fmt.Errorf("error parsing input file %+v ", err)
}
}

err = utils.SetFlagsFromFile(cmd, cmdInputs.Flags)
if err != nil {
return err
}

return nil
},
RunE: execCmdMonitorRunE,
}

func execCmdMonitorRunE(cmd *cobra.Command, args []string) error {
// TODO: Wire up the client
return nil
}
21 changes: 21 additions & 0 deletions internal/synthetics/command_monitor_run_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build unit

package synthetics

import (
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

func TestCmdSyntheticsMonitorRun(t *testing.T) {
cmd := &cobra.Command{
Use: cmdMonitorRun.Use,
RunE: execCmdMonitorRunE,
}

err := cmd.Execute()

assert.NoError(t, err)
}
38 changes: 5 additions & 33 deletions internal/utils/command_do.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"reflect"
"strconv"

"github.com/spf13/cobra"
"gopkg.in/yaml.v3"
Expand Down Expand Up @@ -47,45 +45,19 @@ var cmdDo = &cobra.Command{
}
}

// Validate flags
err = setFlagsFromFile(cmd, cmdInputs.Flags)
err = SetFlagsFromFile(cmd, cmdInputs.Flags)
if err != nil {
return err
}

return nil
},
Run: func(cmd *cobra.Command, args []string) {
fmt.Printf("\n Command - flag from file (guid): %+v", guid)
fmt.Printf("\n Command - flag from file (other): %+v \n\n", otherFlag)
},
RunE: runDoCommandE,
}

// setFlagsFromFile sets the command flag values based on the provided input file contents.
// If also ensures the provided flags from an input file match the expected flags and their respective types.
// Nonexistent flags will result in an error. Incorrect types will result in an error.
func setFlagsFromFile(cmd *cobra.Command, flagsFromFile map[string]interface{}) error {
flagSet := cmd.Flags()
for k, v := range flagsFromFile {
// Ensure flag exists for the command
flag := flagSet.Lookup(k)
if flag == nil {
return fmt.Errorf("error: Invalid flag `%s` provided for command `%s` ", k, cmd.Name())
}

// Ensure correct type
flagType := flag.Value.Type()
if reflect.TypeOf(v).String() != flag.Value.Type() {
return fmt.Errorf("error: Invalid value `%v` for flag `%s` provided for command `%s`. Must be of type %s", v, k, cmd.Name(), flagType)
}

switch t := flag.Value.Type(); t {
case "string":
flagSet.Set(k, v.(string))
case "int":
flagSet.Set(k, strconv.Itoa(v.(int)))
}
}
func runDoCommandE(cmd *cobra.Command, args []string) error {
fmt.Printf("\n Command - flag from file (guid): %+v", guid)
fmt.Printf("\n Command - flag from file (other): %+v \n\n", otherFlag)

return nil
}
Expand Down
21 changes: 21 additions & 0 deletions internal/utils/command_do_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//go:build unit

package utils

import (
"testing"

"github.com/spf13/cobra"
"github.com/stretchr/testify/assert"
)

func TestCmdDo(t *testing.T) {
cmd := &cobra.Command{
Use: cmdDo.Use,
RunE: runDoCommandE,
}

err := cmd.Execute()

assert.NoError(t, err)
}
30 changes: 30 additions & 0 deletions internal/utils/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
"time"

"github.com/mitchellh/go-homedir"
"github.com/spf13/cobra"

log "github.com/sirupsen/logrus"
)
Expand Down Expand Up @@ -185,3 +186,32 @@ func IsExitStatusCode(exitCode int, err error) bool {
exitCodeString := fmt.Sprintf("exit status %d", exitCode)
return strings.Contains(err.Error(), exitCodeString)
}

// SetFlagsFromFile sets the command flag values based on the provided input file contents.
// If also ensures the provided flags from an input file match the expected flags and their respective types.
// Nonexistent flags will result in an error. Incorrect types will result in an error.
func SetFlagsFromFile(cmd *cobra.Command, flagsFromFile map[string]interface{}) error {
flagSet := cmd.Flags()
for k, v := range flagsFromFile {
// Ensure flag exists for the command
flag := flagSet.Lookup(k)
if flag == nil {
return fmt.Errorf("error: Invalid flag `%s` provided for command `%s` ", k, cmd.Name())
}

// Ensure correct type
flagType := flag.Value.Type()
if reflect.TypeOf(v).String() != flag.Value.Type() {
return fmt.Errorf("error: Invalid value `%v` for flag `%s` provided for command `%s`. Must be of type %s", v, k, cmd.Name(), flagType)
}

switch t := flag.Value.Type(); t {
case "string":
flagSet.Set(k, v.(string))
case "int":
flagSet.Set(k, strconv.Itoa(v.(int)))
}
}

return nil
}

0 comments on commit bfd4c0e

Please sign in to comment.