Skip to content

Commit

Permalink
Add --input and --body flags to rdctl list-settings
Browse files Browse the repository at this point in the history
This lets users generate registry files from arbitrary JSON documents.

The problem with `rdctl list-settings --output reg...` is that
it encodes all the settings, while many users will probably want
to lock down a subset of the settings.

Signed-off-by: Eric Promislow <epromislow@suse.com>
  • Loading branch information
ericpromislow committed Jul 3, 2023
1 parent 7a7d5f6 commit 74c9495
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 1 deletion.
77 changes: 77 additions & 0 deletions bats/tests/preferences/generate-reg-output.bats
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
load '../helpers/load'

# No rancher-desktop needed for this test
local_setup() {
if is_windows; then
# We need to use a directory that exists on the Win32 filesystem
# so the ctrctl clients can correctly map the bind mounts.
TEMP="$(win32env TEMP)"
else
TEMP=/tmp
fi
}

verify_registry_output() {
assert_success
assert_output --partial '[HKEY_CURRENT_USER\SOFTWARE\Policies\Rancher Desktop\defaults\containerEngine]'
assert_output --partial '[HKEY_CURRENT_USER\SOFTWARE\Policies\Rancher Desktop\defaults\containerEngine\allowedImages]'
assert_output --partial '[HKEY_CURRENT_USER\SOFTWARE\Policies\Rancher Desktop\defaults\containerEngine\allowedImages]'
assert_output --partial '"patterns"=hex(7):61,00,62,00,63,00,00,00,67,00,68,00,69,00,00,00,64,00,65,00,66,00,00,00,00,00'
assert_output --partial '[HKEY_CURRENT_USER\SOFTWARE\Policies\Rancher Desktop\defaults\WSL\integrations]'
assert_output --partial '"first"=dword:1'
assert_output --partial '"second"=dword:0'
}

@test 'generates registry output from stding' {
run bash -c $'echo \'{"kubernetes": {"enabled": false}, "containerEngine": { "allowedImages": {"patterns": ["abc", "ghi", "def"] } }, "WSL": { "integrations": { "first": true, "second": false } } }\' | rdctl list-settings --output reg,hkcu --input - | cat -n'
verify_registry_output
}

@test 'generates registry output from inline string' {
run rdctl list-settings --output reg,hkcu -b '{"kubernetes": {"enabled": false}, "containerEngine": { "allowedImages": {"patterns": ["abc", "ghi", "def"] } }, "WSL": { "integrations": { "first": true, "second": false } } }'
verify_registry_output
}

@test 'generates registry output from a file' {
local JSONFILE="$TEMP"/rdctl-reg-output.txt
echo '{"kubernetes": {"enabled": false}, "containerEngine": { "allowedImages": {"patterns": ["abc", "ghi", "def"] } }, "WSL": { "integrations": { "first": true, "second": false } } }' >"$JSONFILE"
run rdctl list-settings --output reg,hkcu --input "$JSONFILE"
verify_registry_output
rm -f "$JSONFILE"
}

@test 'complains about both --input and --body' {
run rdctl list-settings --output reg,hkcu --input - --body blip
assert_failure
assert_output "Error: list-settings command: --body|-b and --input options cannot both be specified"
}

@test 'complains about both --input and -b' {
run rdctl list-settings --output reg,hkcu --input - -b blip
assert_failure
assert_output "Error: list-settings command: --body|-b and --input options cannot both be specified"
}

@test 'complains about non-json body' {
run rdctl list-settings --output reg,hkcu --body "ceci n'est pas quelque json"
assert_failure
assert_output "Error: error in json: invalid character 'c' looking for beginning of value"
}

@test 'complains about --body without reg' {
run rdctl list-settings --output json --body "ceci n'est pas quelque json"
assert_failure
assert_output "Error: --input and --body|-b options are only valid when '--output reg' is also specified"
}

@test 'complains about --input without reg' {
run rdctl list-settings --output json --input "ceci n'est pas quelque json"
assert_failure
assert_output "Error: --input and --body|-b options are only valid when '--output reg' is also specified"
}

@test 'complains about --input stdin without reg' {
run rdctl list-settings --input -
assert_failure
assert_output "Error: --input and --body|-b options are only valid when '--output reg' is also specified"
}
40 changes: 39 additions & 1 deletion src/go/rdctl/cmd/listSettings.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import (
"fmt"
"github.com/rancher-sandbox/rancher-desktop/src/go/rdctl/pkg/reg"
"github.com/spf13/cobra"
"io/ioutil"
"os"
"strings"
)

Expand All @@ -28,6 +30,8 @@ var outputSettingsFlags struct {
RegistryHive string
RegistryProfileType string
}
var InputFile string
var JSONBody string

const jsonFormat = "json"
const regFormat = "reg"
Expand All @@ -48,6 +52,20 @@ rdctl list-commands --output reg,X,Y
where X is either "hkcu" or "hklm", depending on whether you want to update HKEY_LOCAL_MACHINE
or HKEY_CURRENT_USER respectively,
and Y is either "defaults" or "locked", depending on which deployment profile you want to populate.
You can convert any arbitrary JSON document to reg file format by specifying either
'--body|-b STRING_CONTAINING_JSON' or
'--input FILE_CONTAINING_JSON' to convert the supplied JSON text, rather than getting the current
settings from the server. Any fields in the JSON that aren't recognized as Rancher Desktop settings
will be ignore.
You can also specify '--input -' to pipe JSON in from standard input.
So something like
echo '{"kubernetes":{"enabled": false}}' | rdctl list-settings --output=reg,hkcu --input - > k8sOff.reg
can be used to produce a registry file that will set 'kubernetes.enabled' to false in the deployment file.
Then run 'reg import k8sOff.reg' to add that hierarchy to the Windows registry.
`,
RunE: func(cmd *cobra.Command, args []string) error {
if err := cobra.NoArgs(cmd, args); err != nil {
Expand All @@ -71,6 +89,8 @@ func init() {
listSettingsCmd.Flags().StringVarP(&outputSettingsFlags.Format, "output", "", jsonFormat, fmt.Sprintf("output format: %s|%s, default %s", jsonFormat, regFormat, jsonFormat))
listSettingsCmd.Flags().StringVarP(&outputSettingsFlags.RegistryHive, "reg-hive", "", "", fmt.Sprintf("registry hive: %s|%s, default %s", reg.HklmRegistryHive, reg.HkcuRegistryHive, reg.HklmRegistryHive))
listSettingsCmd.Flags().StringVarP(&outputSettingsFlags.RegistryProfileType, "section", "", "", fmt.Sprintf("registry section: %s|%s, default %s", defaultsRegistrySection, lockedRegistrySection, defaultsRegistrySection))
listSettingsCmd.Flags().StringVarP(&InputFile, "input", "", "", "File containing JSON payload to upload (- for standard input)")
listSettingsCmd.Flags().StringVarP(&JSONBody, "body", "b", "", "JSON payload to upload")
}

func validateOutputFormatFlags() error {
Expand Down Expand Up @@ -107,7 +127,25 @@ func getListSettings() ([]byte, error) {
if err != nil {
return nil, err
}
output, err := processRequestForUtility(doRequest("GET", versionCommand("", "settings")))
var output []byte

if InputFile != "" && JSONBody != "" {
return nil, fmt.Errorf("list-settings command: --body|-b and --input options cannot both be specified")
}
if InputFile == "" && JSONBody == "" {
output, err = processRequestForUtility(doRequest("GET", versionCommand("", "settings")))
} else {
if outputSettingsFlags.Format != "reg" {
return nil, fmt.Errorf("--input and --body|-b options are only valid when '--output reg' is also specified")
}
if JSONBody != "" {
output = []byte(JSONBody)
} else if InputFile == "-" {
output, err = ioutil.ReadAll(os.Stdin)
} else {
output, err = ioutil.ReadFile(InputFile)
}
}
if err != nil {
return nil, err
} else if outputSettingsFlags.Format == jsonFormat {
Expand Down

0 comments on commit 74c9495

Please sign in to comment.