-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: "device update --locked" should also unlock #485
Open
displague
wants to merge
5
commits into
main
Choose a base branch
from
device-lock
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 4 commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
34ccdcd
fix: "device update --lock" should also unlock
displague bef3873
chore(device update): use Cobra to enforce exclusive fields and no ad…
displague 67dbcd0
docs: revise device update --locked arg
displague f304a91
chore: refactor device update locked to simple bool
displague c6562a2
test: add e2e test for device update --locked=true|false
displague File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,7 +34,6 @@ import ( | |
func (c *Client) Update() *cobra.Command { | ||
var ( | ||
description string | ||
locked bool | ||
userdata string | ||
userdataFile string | ||
hostname string | ||
|
@@ -46,7 +45,7 @@ func (c *Client) Update() *cobra.Command { | |
) | ||
// updateDeviceCmd represents the updateDevice command | ||
updateDeviceCmd := &cobra.Command{ | ||
Use: `update -i <device_id> [-H <hostname>] [-d <description>] [--locked <boolean>] [-t <tags>] [-u <userdata> | --userdata-file <filepath>] [-c <customdata>] [-s <ipxe_script_url>] [--always-pxe=<true|false>]`, | ||
Use: `update -i <device_id> [-H <hostname>] [-d <description>] [--locked=<true|false>] [-t <tags>] [-u <userdata> | --userdata-file <filepath>] [-c <customdata>] [-s <ipxe_script_url>] [--always-pxe=<true|false>]`, | ||
Short: "Updates a device.", | ||
Long: "Updates the hostname of a device. Updates or adds a description, tags, userdata, custom data, and iPXE settings for an already provisioned device. Can also lock or unlock future changes to the device.", | ||
Example: ` # Updates the hostname of a device: | ||
|
@@ -64,10 +63,6 @@ func (c *Client) Update() *cobra.Command { | |
deviceUpdate.Description = &description | ||
} | ||
|
||
if userdata != "" && userdataFile != "" { | ||
return fmt.Errorf("either userdata or userdata-file should be set") | ||
} | ||
|
||
if userdataFile != "" { | ||
userdataRaw, readErr := os.ReadFile(userdataFile) | ||
if readErr != nil { | ||
|
@@ -80,7 +75,11 @@ func (c *Client) Update() *cobra.Command { | |
deviceUpdate.Userdata = &userdata | ||
} | ||
|
||
if locked { | ||
if cmd.Flag("locked").Changed { | ||
locked, err := cmd.Flags().GetBool("locked") | ||
if err != nil { | ||
return fmt.Errorf("could not parse locked value: %w", err) | ||
} | ||
deviceUpdate.Locked = &locked | ||
} | ||
|
||
|
@@ -123,12 +122,13 @@ func (c *Client) Update() *cobra.Command { | |
updateDeviceCmd.Flags().StringVarP(&description, "description", "d", "", "Adds or updates the description for the device.") | ||
updateDeviceCmd.Flags().StringVarP(&userdata, "userdata", "u", "", "Adds or updates the userdata for the device.") | ||
updateDeviceCmd.Flags().StringVarP(&userdataFile, "userdata-file", "", "", "Path to a userdata file for device initialization. Can not be used with --userdata.") | ||
updateDeviceCmd.Flags().BoolVarP(&locked, "locked", "l", false, "Locks or unlocks the device for future changes (<true|false>).") | ||
updateDeviceCmd.Flags().BoolP("locked", "l", false, "Locks or unlocks the device for future changes (<true|false>).") | ||
updateDeviceCmd.Flags().StringSliceVarP(&tags, "tags", "t", []string{}, `Adds or updates the tags for the device --tags="tag1,tag2".`) | ||
updateDeviceCmd.Flags().BoolVarP(&alwaysPXE, "always-pxe", "a", false, "Updates the always_pxe toggle for the device (<true|false>).") | ||
updateDeviceCmd.Flags().StringVarP(&ipxescripturl, "ipxe-script-url", "s", "", "Add or update the URL of the iPXE script.") | ||
updateDeviceCmd.Flags().StringVarP(&customdata, "customdata", "c", "", "Adds or updates custom data to be included with your device's metadata.") | ||
_ = updateDeviceCmd.MarkFlagRequired("id") | ||
|
||
updateDeviceCmd.MarkFlagsMutuallyExclusive("userdata", "userdata-file") | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $ PACKNGO_DEBUG=1 go run ./cmd/metal device update --locked false --id 1234 --userdata foo --userdata-file=/tmp/foo
Error: if any flags in the group [userdata userdata-file] are set none of the others can be; [userdata userdata-file] were all set
Usage:
... Surprisingly, this does not affect |
||
updateDeviceCmd.Args = cobra.NoArgs | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. $ PACKNGO_DEBUG=1 go run ./cmd/metal device update --locked false --id 1234 fkk fll
Error: unknown command "fkk" for "metal device update" |
||
return updateDeviceCmd | ||
} |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A test for lock/unlock would build confidence that we've fixed the issue
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started down a path of introducing a mock because I don't like the idea of spinning up and settling electrified and cooled rust to verify that a few bytes of command line argument trigger a few bytes of json in an HTTP call.
221430d
The test in the sha is not clean or complete, but it does trigger the lock in the CLI args and look for the request to contain the expected JSON.
Alternatively, I could add steps to the existing "update" E2E to see if the resource
locked
state can be toggled on and off again (which would be needed for a successful cleanup).Interested in your thoughts on a preferred path, @ctreatma.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have a strong preference either way for whether the test hits a live API or a mock. If we're going to mock I think it's better to set up a mock API than to inject a mock HTTP transport, since that more closely matches real usage, reduces the risk of accidentally mocking out some custom behavior, and provides a more straightforward path to maybe eventually adopting a mock that is generated from the API spec.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ctreatma added in c6562a2