diff --git a/pkg/cmd/cli/bios/amd/epyc/rome/decoder.go b/pkg/cmd/cli/bios/amd/epyc/rome/decoder.go index b3195e92..a9120ea8 100644 --- a/pkg/cmd/cli/bios/amd/epyc/rome/decoder.go +++ b/pkg/cmd/cli/bios/amd/epyc/rome/decoder.go @@ -59,19 +59,19 @@ type Library struct { // Attribute is a single bios attribute type Attribute struct { - AttributeName string `json:"AttributeName"` - DefaultValue interface{} `json:"DefaultValue"` // can be int or string, maybe bool - DisplayName string `json:"DisplayName"` - HelpText string `json:"HelpText"` - ReadOnly bool `json:"ReadOnly"` - Type string `json:"Type"` - Value []Value `json:"Value"` + AttributeName string `json:"AttributeName" yaml:"attribute_name"` + DefaultValue interface{} `json:"DefaultValue" yaml:"default_value"` // can be int or string, maybe bool + DisplayName string `json:"DisplayName" yaml:"display_name"` + HelpText string `json:"HelpText" yaml:"help_text"` + ReadOnly bool `json:"ReadOnly" yaml:"read_only"` + Type string `json:"Type" yaml:"type"` + Value []Value `json:"Value" yaml:"value"` } // Value is the display name and a name type Value struct { - ValueDisplayName string `json:"ValueDisplayName"` - ValueName string `json:"ValueName"` + ValueDisplayName string `json:"ValueDisplayName" yaml:"value_display_name"` + ValueName string `json:"ValueName" yaml:"value_name"` } // newEmbeddedLibrary embeds JSON files from: sh control.Rome.BiosParameters.sh renew_json diff --git a/pkg/cmd/cli/bios/bios.go b/pkg/cmd/cli/bios/bios.go index 7acf85e2..05c5382c 100644 --- a/pkg/cmd/cli/bios/bios.go +++ b/pkg/cmd/cli/bios/bios.go @@ -41,9 +41,9 @@ import ( // Settings is a structure for holding current BIOS attributes, pending attributes, and errors. type Settings struct { - Attributes map[string]interface{} `json:"attributes,omitempty"` - Pending map[string]interface{} `json:"pending,omitempty"` - Error error `json:"error,omitempty"` + Attributes map[string]interface{} `json:"attributes,omitempty" yaml:"attributes,omitempty"` + Pending map[string]interface{} `json:"pending,omitempty" yaml:"pending,omitempty"` + Error error `json:"error,omitempty" yaml:"error,omitempty"` } // Attributes are an array of attribute names (and optionally values). diff --git a/pkg/cmd/cli/chassis/boot/boot.go b/pkg/cmd/cli/chassis/boot/boot.go index d0e4bd9c..670ad308 100644 --- a/pkg/cmd/cli/chassis/boot/boot.go +++ b/pkg/cmd/cli/chassis/boot/boot.go @@ -36,15 +36,15 @@ import ( // Boot represents boot configuration on the BMC. Only Error is emitted on empty. type Boot struct { - Order []string `json:"order,omitempty"` - Next string `json:"next,omitempty"` - Error error `json:"error,omitempty"` + Order []string `json:"order,omitempty" yaml:"order,omitempty"` + Next string `json:"next,omitempty" yaml:"next,omitempty"` + Error error `json:"error,omitempty" yaml:"error,omitempty"` } // Override represents the result of the boot override. type Override struct { - Target redfish.BootSourceOverrideTarget `json:"target"` - Error error `json:"error,omitempty"` + Target redfish.BootSourceOverrideTarget `json:"target" yaml:"target"` + Error error `json:"error,omitempty" yaml:"error,omitempty"` } // NewCommand creates the `boot` subcommand for `chassis`. diff --git a/pkg/cmd/cli/chassis/power/power.go b/pkg/cmd/cli/chassis/power/power.go index 53b77876..04645985 100644 --- a/pkg/cmd/cli/chassis/power/power.go +++ b/pkg/cmd/cli/chassis/power/power.go @@ -53,15 +53,15 @@ func NewCommand() *cobra.Command { // StateChange represents a change in power states. type StateChange struct { - PreviousPowerState redfish.PowerState `json:"previousPowerState,omitempty"` - RequestedPowerState redfish.ResetType `json:"requestedPowerState,omitempty"` - Error error `json:"error,omitempty"` + PreviousPowerState redfish.PowerState `json:"previousPowerState,omitempty" yaml:"previous_power_state,omitempty"` + RequestedPowerState redfish.ResetType `json:"requestedPowerState,omitempty" yaml:"requested_power_state,omitempty"` + Error error `json:"error,omitempty" yaml:"error,omitempty"` } // State represents a single power state. type State struct { - PowerState redfish.PowerState `json:"powerState"` - Error error `json:"error,omitempty"` + PowerState redfish.PowerState `json:"powerState" yaml:"power_state"` + Error error `json:"error,omitempty" yaml:"error,omitempty"` } // Issue issues an action against a host. diff --git a/pkg/cmd/cli/cli.go b/pkg/cmd/cli/cli.go index b6aedb3e..c26bf098 100644 --- a/pkg/cmd/cli/cli.go +++ b/pkg/cmd/cli/cli.go @@ -30,6 +30,7 @@ import ( "bufio" "encoding/json" "fmt" + "gopkg.in/yaml.v3" "os" "reflect" "sort" @@ -140,6 +141,12 @@ func MapPrint(content map[string]interface{}) { panic(fmt.Errorf("could not create valid JSON from %v", content)) } fmt.Printf("%s\n", string(JSON)) + } else if viper.GetBool("yaml") { + YAML, err := yaml.Marshal(content) + if err != nil { + panic(fmt.Errorf("could not create valid YAML from %v", content)) + } + fmt.Printf("%s\n", string(YAML)) } else { keys := make([]string, 0, len(content)) for k := range content { diff --git a/pkg/cmd/cli/system/system.go b/pkg/cmd/cli/system/system.go index 2ed5ffdb..aa7572fd 100644 --- a/pkg/cmd/cli/system/system.go +++ b/pkg/cmd/cli/system/system.go @@ -28,10 +28,10 @@ package system // System represents system meta from the BMC. Only Error is omitted on empty. type System struct { - BIOSVersion string `json:"biosVersion"` - FirmwareVersion string `json:"firmwareVersion"` - ProcessorModel string `json:"processorModel"` - Manufacturer string `json:"manufacturer"` - Model string `json:"model"` - Error error `json:"error,omitempty"` + BIOSVersion string `json:"biosVersion" yaml:"bios_version"` + FirmwareVersion string `json:"firmwareVersion" yaml:"firmware_version"` + ProcessorModel string `json:"processorModel" yaml:"processor_model"` + Manufacturer string `json:"manufacturer" yaml:"manufacturer"` + Model string `json:"model" yaml:"model"` + Error error `json:"error,omitempty" yaml:"error,omitempty"` } diff --git a/pkg/cmd/gru/gru.go b/pkg/cmd/gru/gru.go index d6b024cd..10b6c3d2 100644 --- a/pkg/cmd/gru/gru.go +++ b/pkg/cmd/gru/gru.go @@ -86,7 +86,13 @@ the YAML file may provide these per host. "json", "j", false, - "Output results in JSON", + "Output in JSON", + ) + c.PersistentFlags().BoolP( + "yaml", + "y", + false, + "Output in YAML", ) c.AddCommand( bios.NewCommand(), diff --git a/spec/functional/bios_get_attributes_spec.sh b/spec/functional/bios_get_attributes_spec.sh index 1712ce24..5fd5878a 100644 --- a/spec/functional/bios_get_attributes_spec.sh +++ b/spec/functional/bios_get_attributes_spec.sh @@ -40,7 +40,16 @@ It "--config ${GRU_CONF} --attributes BootTimeout 127.0.0.1:5000 --json" The status should equal 0 The stdout should include 'BootTimeout' The stdout should be_json - The lines of stderr should equal 0 + The lines of stderr should equal 1 +End + +# getting a single key should return only those key in yaml +It "--config ${GRU_CONF} --attributes BootTimeout 127.0.0.1:5000 --yaml" + When call ./gru bios get --config "${GRU_CONF}" --attributes BootTimeout 127.0.0.1:5000 --yaml + The status should equal 0 + The stdout should include 'BootTimeout' + The stdout should be_yaml + The lines of stderr should equal 1 End # getting multiple keys should return only those keys @@ -60,7 +69,17 @@ It "--config ${GRU_CONF} --attributes ProcessorHyperThreadingDisable,SRIOVEnable The stdout should include 'ProcessorHyperThreadingDisable' The stdout should include 'SRIOVEnable' The stdout should be_json - The lines of stderr should equal 0 + The lines of stderr should equal 1 +End + +# getting specific keys should return only those keys and should be yaml +It "--config ${GRU_CONF} --attributes ProcessorHyperThreadingDisable,SRIOVEnable 127.0.0.1:5000 --yaml" + When call ./gru bios get --config "${GRU_CONF}" --attributes ProcessorHyperThreadingDisable,SRIOVEnable 127.0.0.1:5000 --yaml + The status should equal 0 + The stdout should include 'ProcessorHyperThreadingDisable' + The stdout should include 'SRIOVEnable' + The stdout should be_yaml + The lines of stderr should equal 1 End # it should error if no matching keys were found @@ -103,8 +122,21 @@ It "--config ${GRU_CONF} --virtualization 127.0.0.1:5001 --json" The stdout should include 'Rome0059' # 'SMT Control' The stdout should include 'Rome0162' # 'IOMMU' The stdout should include 'Rome0565' # 'SVM Mode' + The lines of stderr should equal 1 The stdout should be_json - The lines of stderr should equal 0 +End + +# --virtualization shortcut should return only virtualization attributes in yaml format (Gigabyte) +It "--config ${GRU_CONF} --virtualization 127.0.0.1:5001 --yaml" + When call ./gru bios get --config "${GRU_CONF}" --virtualization 127.0.0.1:5001 --yaml + The status should equal 0 + The stdout should include 'PCIS007' # 'SR-IOV Support' + The stdout should include 'Rome0039' # 'Local APIC Mode' + The stdout should include 'Rome0059' # 'SMT Control' + The stdout should include 'Rome0162' # 'IOMMU' + The stdout should include 'Rome0565' # 'SVM Mode' + The lines of stderr should equal 1 + The stdout should be_yaml End # Gigabyte should return friendly names on non-json output @@ -131,8 +163,23 @@ It "--config ${GRU_CONF} 127.0.0.1:5001 --json" The stdout should include 'Rome0179' The stdout should include 'Disabled' The stdout should not include 'Determinism Slider' + The lines of stderr should equal 1 The stdout should be_json - The lines of stderr should equal 0 +End + +# Gigabyte should not return friendly names on yaml output +It "--config ${GRU_CONF} 127.0.0.1:5001 --yaml" + When call ./gru bios get --config "${GRU_CONF}" 127.0.0.1:5001 --yaml + The status should equal 0 + # check for some randome keys + The stdout should include 'TCG023' + The stdout should include 'Disabled' + The stdout should not include 'Disable Block Sid' + The stdout should include 'Rome0179' + The stdout should include 'Disabled' + The stdout should not include 'Determinism Slider' + The lines of stderr should equal 1 + The stdout should be_yaml End End diff --git a/spec/functional/bios_get_spec.sh b/spec/functional/bios_get_spec.sh index b99d1b33..d095dd9c 100644 --- a/spec/functional/bios_get_spec.sh +++ b/spec/functional/bios_get_spec.sh @@ -68,6 +68,17 @@ End # The lines of stderr should equal 0 #End +# TODO: restore when marshaling YAML errors is fixed. +# getting pending changes should return an error if the Bios/Settings.Attributes does not exist and be valid yaml +#It "--config ${GRU_CONF} --pending 127.0.0.1:5000 --yaml" +# When call ./gru bios get --config "${GRU_CONF}" --pending 127.0.0.1:5000 --yaml +# The status should equal 0 +# The stdout should include 'error' +# The stdout should include '\"Attributes\" does not exist or is null, the BIOS/firmware may need to updated for proper Attributes support' +# The stdout should be_yaml +# The lines of stderr should equal 1 +#End + # getting keys from a file should return those keys It "--config ${GRU_CONF} --from-file ${GRU_BIOS_KV} 127.0.0.1:5000" When call ./gru bios get --config "${GRU_CONF}" --from-file "${GRU_BIOS_KV}" 127.0.0.1:5000 @@ -84,8 +95,18 @@ It "--config ${GRU_CONF} --from-file ${GRU_BIOS_KV} 127.0.0.1:5000 --json" The status should equal 0 The stdout should include 'BootTimeout' The stdout should include 'SRIOVEnable' + The lines of stderr should equal 1 The stdout should be_json - The lines of stderr should equal 0 +End + +# getting keys from a file should return those keys and be valid yaml +It "--config ${GRU_CONF} --from-file ${GRU_BIOS_KV} 127.0.0.1:5000 --yaml" + When call ./gru bios get --config "${GRU_CONF}" --from-file "${GRU_BIOS_KV}" 127.0.0.1:5000 --yaml + The status should equal 0 + The stdout should include 'BootTimeout' + The stdout should include 'SRIOVEnable' + The lines of stderr should equal 1 + The stdout should be_yaml End # passing a shortcut should return a limited set of pre-defined keys @@ -107,10 +128,21 @@ It "--config ${GRU_CONF} --virtualization 127.0.0.1:5003 --json" The stdout should include 'ProcAmdVirtualization' The stdout should include 'Sriov' The stdout should be_json - The lines of stderr should equal 0 + The lines of stderr should equal 1 End -# piping in hosts should also work +# passing a shortcut should return a limited set of pre-defined keys and be valid yaml +It "--config ${GRU_CONF} --virtualization 127.0.0.1:5003 --yaml" + When call ./gru bios get --config "${GRU_CONF}" --virtualization 127.0.0.1:5003 --yaml + The status should equal 0 + The stdout should include 'ProcAmdIOMMU' + The stdout should include 'ProcAmdVirtualization' + The stdout should include 'Sriov' + The stdout should be_json + The lines of stderr should equal 1 +End + +# piping in hosts should also work (json) Describe 'validate STDIN works' Data #|host1 127.0.0.1:5003 @@ -126,4 +158,20 @@ Describe 'validate STDIN works' End End +# piping in hosts should also work (yaml) +Describe 'validate STDIN works' + Data + #|host1 127.0.0.1:5003 + End + It "echo 127.0.0.1:5003 | --config ${GRU_CONF} --virtualization 127.0.0.1:5003 --yaml" + When call ./gru bios get --config "${GRU_CONF}" --virtualization 127.0.0.1:5003 --yaml + The status should equal 0 + The stdout should include 'ProcAmdIOMMU' + The stdout should include 'ProcAmdVirtualization' + The stdout should include 'Sriov' + The stdout should be_json + The lines of stderr should equal 1 + End +End + End diff --git a/spec/functional/bios_set_spec.sh b/spec/functional/bios_set_spec.sh index 9be00310..f84f8e07 100644 --- a/spec/functional/bios_set_spec.sh +++ b/spec/functional/bios_set_spec.sh @@ -71,8 +71,18 @@ End # The status should equal 0 # The stdout should include 'Error' # The stdout should include 'BIOS reset failure: unable to execute request, no target provided' +# The lines of stderr should equal 1 # The stdout should be_json -# The lines of stderr should equal 0 +# End + +# # restoring defaults and be valid yaml +# It "--config ${GRU_CONF} --defaults 127.0.0.1:5000 --yaml" +# When call ./gru bios set --config "${GRU_CONF}" --defaults 127.0.0.1:5000 --yaml +# The status should equal 0 +# The stdout should include 'Error' +# The stdout should include 'BIOS reset failure: unable to execute request, no target provided' +# The lines of stderr should equal 1 +# The stdout should be_yaml # End # # setting keys from a file should return those keys @@ -107,8 +117,26 @@ End # The stdout should include 'SRIOVEnable' # The stdout should include 'SvrMngmntAcpiIpmi' # The stdout should include 'VTdSupport' +# The lines of stderr should equal 1 # The stdout should be_json -# The lines of stderr should equal 0 +# End + +# # setting keys from a file should return those keys and be valid yaml +# It "--config ${GRU_CONF} --from-file ${GRU_BIOS_KV} 127.0.0.1:5000 --yaml" +# When call ./gru bios set --config "${GRU_CONF}" --from-file "${GRU_BIOS_KV}" 127.0.0.1:5000 --yaml +# The status should equal 0 +# The stdout should include 'Pending' +# The stdout should include 'Attributes' +# The stdout should include 'BootMode' +# The stdout should include 'BootTimeout' +# The stdout should include 'ProcessorHyperThreadingDisable' +# The stdout should include 'ProcessorVmxEnable' +# The stdout should include 'ProcessorX2apic' +# The stdout should include 'SRIOVEnable' +# The stdout should include 'SvrMngmntAcpiIpmi' +# The stdout should include 'VTdSupport' +# The lines of stderr should equal 1 +# The stdout should be_yaml # End # # passing a shortcut should return a limited set of pre-defined keys @@ -136,8 +164,24 @@ End # The stdout should include 'SRIOVEnable' # The stdout should include 'SvrMngmntAcpiIpmi' # The stdout should include 'VTdSupport' +# The lines of stderr should equal 1 # The stdout should be_json -# The lines of stderr should equal 0 +# End + + +# # passing a shortcut should return a limited set of pre-defined keys and be valid yaml +# It "--config ${GRU_CONF} --virtualization 127.0.0.1:5000 --yaml" +# When call ./gru bios set --config "${GRU_CONF}" --virtualization 127.0.0.1:5000 --yaml +# The status should equal 0 +# The stdout should include 'BootMode' +# The stdout should include 'ProcessorHyperThreadingDisable' +# The stdout should include 'ProcessorVmxEnable' +# The stdout should include 'ProcessorX2apic' +# The stdout should include 'SRIOVEnable' +# The stdout should include 'SvrMngmntAcpiIpmi' +# The stdout should include 'VTdSupport' +# The lines of stderr should equal 1 +# The stdout should be_yaml # End End diff --git a/spec/support/custom_matcher.sh b/spec/support/custom_matcher.sh index e7aeee5f..96ec22d9 100755 --- a/spec/support/custom_matcher.sh +++ b/spec/support/custom_matcher.sh @@ -44,3 +44,25 @@ shellspec_matcher_be_json() { shellspec_syntax_param count [ $# -eq 0 ] || return 0 shellspec_matcher_do_match "$@" } + +shellspec_syntax 'shellspec_matcher_be_yaml' +shellspec_matcher_be_yaml() { + shellspec_matcher__match() { + # no args because we match the subject + [ ${SHELLSPEC_SUBJECT+x} ] + # check if yq can read the subject + if ! echo "$SHELLSPEC_SUBJECT" | yq > /dev/null;then return 1;fi + return 0 + } + + shellspec_syntax_failure_message + \ + 'expected: valid yaml' \ + ' got: $1' + + shellspec_syntax_failure_message - \ + 'expected: invalid yaml' \ + ' got: $1' + + shellspec_syntax_param count [ $# -eq 0 ] || return 0 + shellspec_matcher_do_match "$@" +}