feat(cli): complete CLI with full CRUD operations (#563)#621
feat(cli): complete CLI with full CRUD operations (#563)#621ArangoGutierrez merged 23 commits intoNVIDIA:mainfrom
Conversation
Design for issue NVIDIA#563 covering: - New CLI commands (describe, get, ssh, scp, update) - Global verbosity flags (-q, -v, -d) - Output formatting infrastructure - Implementation tasks and testing strategy Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Detailed task-by-task implementation plan for: - Global verbosity flags (-q, -v, -d) - Unit tests for all new CLI commands - Output formatter tests 11 tasks with TDD approach and commit checkpoints. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Add Verbosity type with four levels (Quiet, Normal, Verbose, Debug) to control log output. Info, Check, and Warning methods now respect verbosity settings, while Error always prints. New Debug and Trace methods provide additional logging granularity for troubleshooting. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Add global flags for controlling output verbosity: - --quiet, -q: Suppress non-error output - --verbose: Enable verbose output - --debug, -d: Enable debug-level logging (also reads DEBUG env var) Flag precedence: --debug > --verbose > --quiet Note: -v was not used for --verbose to avoid conflict with built-in --version flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Rename the --quiet flag to --ids-only to avoid conflict with the new global --quiet flag that controls verbosity. The --ids-only flag now only outputs instance IDs, one per line. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Add comprehensive unit tests for the pkg/output package covering: - ValidFormats() and IsValidFormat() validation functions - NewFormatter() with empty, valid, and invalid format inputs - Formatter.Format() accessor method - PrintJSON() with struct, map, and slice data types - PrintYAML() with struct, map, and nested struct data - Print() dispatch logic for JSON, YAML, and table formats - PrintTable() with mock TableData interface - TablePrinter fluent interface (Header, Row, Flush) - SetWriter() for output redirection - Error message quality for invalid formats Achieves 97.9% code coverage. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Adds pkg/output with Formatter, TablePrinter, and TableData interface for consistent output formatting across all CLI commands. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Adds -o flag (json/yaml/table) to holodeck status with structured output types for JSON/YAML serialization. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
New commands for issue NVIDIA#563: - describe: detailed instance introspection with JSON/YAML output - get kubeconfig: download kubeconfig from instance - get ssh-config: generate SSH config entry - ssh: SSH into instance or run remote commands - scp: copy files to/from instance via SFTP - update: update instance configuration (add components, labels) All commands include unit tests for core logic. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Updates list_test.go to use --ids-only instead of the old --quiet/-q flag which was renamed to avoid conflict with the global -q flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
C1: Add nil check for env.Labels before writing provisioned label
in update --reprovision. Previously panicked when no --label flags
were provided and the cached environment had no labels.
C2: Replace incorrect containsSpace+fmt.Sprintf("%q") quoting with
simple strings.Join. SSH session.Run always passes through the
remote shell, so Go-style quoting was wrong. Document this behavior.
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
- Extract getHostURL and connectSSH into cmd/cli/common package, eliminating duplication across ssh, scp, and get commands (I1) - Use path instead of filepath for remote SFTP paths to ensure correct POSIX separators on all platforms (I2) - Log warnings for skipped files during recursive remote copy (I3) - Use c.IsSet() for flags with defaults to prevent overwriting existing config with default values (I4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
ef73606 to
fb19ac0
Compare
Pull Request Test Coverage Report for Build 21752525231Details
💛 - Coveralls |
There was a problem hiding this comment.
Pull request overview
This PR implements a comprehensive set of CLI CRUD operations to complete the Holodeck CLI (#563), adding essential features for managing GPU-ready cloud environments. The changes introduce global verbosity levels, structured output formatting, and critical SSH/file transfer capabilities.
Changes:
- Added logger verbosity system (Quiet/Normal/Verbose/Debug) with corresponding flags (-q, --verbose, -d)
- Created
pkg/outputpackage for consistent JSON/YAML/table formatting across commands - Implemented six new commands: describe, get (kubeconfig/ssh-config), ssh, scp, and update
- Refactored
listcommand to support output formats and renamed--quietto--ids-only - Created shared
cmd/cli/commonpackage withGetHostURLandConnectSSHutilities
Reviewed changes
Copilot reviewed 21 out of 21 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| internal/logger/logger.go | Added verbosity levels (Quiet/Normal/Verbose/Debug) with new Debug() and Trace() methods |
| internal/logger/logger_test.go | Comprehensive unit tests for verbosity filtering and methods |
| pkg/output/output.go | Formatter interface with table/JSON/YAML support and TableData interface |
| pkg/output/output_test.go | 732 lines of tests covering all output formats and edge cases |
| cmd/cli/common/host.go | Shared GetHostURL and ConnectSSH utilities (contains bug) |
| cmd/cli/describe/describe.go | Detailed instance introspection with multi-format output |
| cmd/cli/get/get.go | Kubeconfig download and SSH config generation subcommands |
| cmd/cli/ssh/ssh.go | Interactive SSH and remote command execution |
| cmd/cli/scp/scp.go | SFTP file transfer with recursive directory support, proper POSIX path handling |
| cmd/cli/update/update.go | Add components, labels, and re-provision instances (contains bug) |
| cmd/cli/list/list.go | Refactored with output formatting, renamed --quiet to --ids-only |
| cmd/cli/status/status.go | Added output formatting with --output flag |
| cmd/cli/main.go | Integrated global verbosity flags and new commands |
| } | ||
| } | ||
| case v1alpha1.ProviderSSH: | ||
| return env.Spec.HostUrl, nil |
There was a problem hiding this comment.
The field path should be env.Spec.Instance.HostUrl not env.Spec.HostUrl. The HostUrl field is defined on the Instance struct, not directly on EnvironmentSpec. This will cause a compilation error or runtime panic.
| return env.Spec.HostUrl, nil | |
| if env.Spec.Instance != nil { | |
| return env.Spec.Instance.HostUrl, nil | |
| } |
cmd/cli/update/update.go
Outdated
| } | ||
| } | ||
| } else if env.Spec.Provider == v1alpha1.ProviderSSH { | ||
| hostUrl = env.Spec.HostUrl |
There was a problem hiding this comment.
The field path should be env.Spec.Instance.HostUrl not env.Spec.HostUrl. The HostUrl field is defined on the Instance struct, not directly on EnvironmentSpec. This will cause a compilation error or runtime panic.
| hostUrl = env.Spec.HostUrl | |
| if env.Spec.Instance == nil { | |
| return fmt.Errorf("instance spec is required for SSH provider") | |
| } | |
| hostUrl = env.Spec.Instance.HostUrl |
- Fix gofmt, gosec, staticcheck, unconvert, and errcheck lint issues - Promote gopkg.in/yaml.v3 from indirect to direct dependency - Remove planning documents (development artifacts) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
5f98a33 to
8440213
Compare
Address CodeQL alert NVIDIA#6 (go/insecure-hostkeycallback) by replacing the inaccurate comment about "no pre-established host keys". The env file requires SSH authentication keys (client-to-server), but server host keys are a separate concern — they are generated at instance boot with no trusted distribution channel to the client. The security trade-off is now explicitly documented with CWE reference. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
… (S1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Move duplicate GetHostURL tests from cmd/cli/get/ and cmd/cli/ssh/ into cmd/cli/common/host_test.go. Merge overlapping test cases and add a new TestGetHostURL_Cluster_FallbackToFirstNode case that covers the fallback path when no control-plane node exists. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Verbosity is an iota (0-3) so the int->int32 cast cannot overflow. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
8e9a8eb to
607a329
Compare
…A#621) * docs: add CLI CRUD and verbosity design document Design for issue NVIDIA#563 covering: - New CLI commands (describe, get, ssh, scp, update) - Global verbosity flags (-q, -v, -d) - Output formatting infrastructure - Implementation tasks and testing strategy Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs: add CLI CRUD implementation plan Detailed task-by-task implementation plan for: - Global verbosity flags (-q, -v, -d) - Unit tests for all new CLI commands - Output formatter tests 11 tasks with TDD approach and commit checkpoints. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(logger): add verbosity levels with Debug and Trace methods Add Verbosity type with four levels (Quiet, Normal, Verbose, Debug) to control log output. Info, Check, and Warning methods now respect verbosity settings, while Error always prints. New Debug and Trace methods provide additional logging granularity for troubleshooting. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add global verbosity flags (-q, --verbose, -d) Add global flags for controlling output verbosity: - --quiet, -q: Suppress non-error output - --verbose: Enable verbose output - --debug, -d: Enable debug-level logging (also reads DEBUG env var) Flag precedence: --debug > --verbose > --quiet Note: -v was not used for --verbose to avoid conflict with built-in --version flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): rename list --quiet to --ids-only Rename the --quiet flag to --ids-only to avoid conflict with the new global --quiet flag that controls verbosity. The --ids-only flag now only outputs instance IDs, one per line. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(output): add unit tests for output formatting package Add comprehensive unit tests for the pkg/output package covering: - ValidFormats() and IsValidFormat() validation functions - NewFormatter() with empty, valid, and invalid format inputs - Formatter.Format() accessor method - PrintJSON() with struct, map, and slice data types - PrintYAML() with struct, map, and nested struct data - Print() dispatch logic for JSON, YAML, and table formats - PrintTable() with mock TableData interface - TablePrinter fluent interface (Header, Row, Flush) - SetWriter() for output redirection - Error message quality for invalid formats Achieves 97.9% code coverage. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(output): add output formatting package with table/JSON/YAML support Adds pkg/output with Formatter, TablePrinter, and TableData interface for consistent output formatting across all CLI commands. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add output formatting to status command Adds -o flag (json/yaml/table) to holodeck status with structured output types for JSON/YAML serialization. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add describe, get, ssh, scp, update commands with tests New commands for issue NVIDIA#563: - describe: detailed instance introspection with JSON/YAML output - get kubeconfig: download kubeconfig from instance - get ssh-config: generate SSH config entry - ssh: SSH into instance or run remote commands - scp: copy files to/from instance via SFTP - update: update instance configuration (add components, labels) All commands include unit tests for core logic. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(list): update tests for --ids-only flag rename Updates list_test.go to use --ids-only instead of the old --quiet/-q flag which was renamed to avoid conflict with the global -q flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): fix nil map panic and SSH command quoting C1: Add nil check for env.Labels before writing provisioned label in update --reprovision. Previously panicked when no --label flags were provided and the cached environment had no labels. C2: Replace incorrect containsSpace+fmt.Sprintf("%q") quoting with simple strings.Join. SSH session.Run always passes through the remote shell, so Go-style quoting was wrong. Document this behavior. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract shared utilities and fix review issues - Extract getHostURL and connectSSH into cmd/cli/common package, eliminating duplication across ssh, scp, and get commands (I1) - Use path instead of filepath for remote SFTP paths to ensure correct POSIX separators on all platforms (I2) - Log warnings for skipped files during recursive remote copy (I3) - Use c.IsSet() for flags with defaults to prevent overwriting existing config with default values (I4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(ci): resolve lint issues, update go.mod, and remove plan docs - Fix gofmt, gosec, staticcheck, unconvert, and errcheck lint issues - Promote gopkg.in/yaml.v3 from indirect to direct dependency - Remove planning documents (development artifacts) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(security): correct misleading host key comments (CWE-322) Address CodeQL alert NVIDIA#6 (go/insecure-hostkeycallback) by replacing the inaccurate comment about "no pre-established host keys". The env file requires SSH authentication keys (client-to-server), but server host keys are a separate concern — they are generated at instance boot with no trusted distribution channel to the client. The security trade-off is now explicitly documented with CWE reference. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): use common.GetHostURL in update runProvision (S4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): consolidate update command cache file writes (C2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add -q as alias for --ids-only for backwards compatibility (S1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract SSH retry constants in ConnectSSH (S2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs(cli): document SSH remote command quoting behavior (S3) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): warnings always print regardless of verbosity (M1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): consolidate GetHostURL tests into common package (M3) Move duplicate GetHostURL tests from cmd/cli/get/ and cmd/cli/ssh/ into cmd/cli/common/host_test.go. Merge overlapping test cases and add a new TestGetHostURL_Cluster_FallbackToFirstNode case that covers the fallback path when no control-plane node exists. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): make Verbosity thread-safe with atomic.Int32 (M6) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): add nolint directive for gosec G115 in SetVerbosity Verbosity is an iota (0-3) so the int->int32 cast cannot overflow. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> --------- Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…A#621) * docs: add CLI CRUD and verbosity design document Design for issue NVIDIA#563 covering: - New CLI commands (describe, get, ssh, scp, update) - Global verbosity flags (-q, -v, -d) - Output formatting infrastructure - Implementation tasks and testing strategy Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs: add CLI CRUD implementation plan Detailed task-by-task implementation plan for: - Global verbosity flags (-q, -v, -d) - Unit tests for all new CLI commands - Output formatter tests 11 tasks with TDD approach and commit checkpoints. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(logger): add verbosity levels with Debug and Trace methods Add Verbosity type with four levels (Quiet, Normal, Verbose, Debug) to control log output. Info, Check, and Warning methods now respect verbosity settings, while Error always prints. New Debug and Trace methods provide additional logging granularity for troubleshooting. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add global verbosity flags (-q, --verbose, -d) Add global flags for controlling output verbosity: - --quiet, -q: Suppress non-error output - --verbose: Enable verbose output - --debug, -d: Enable debug-level logging (also reads DEBUG env var) Flag precedence: --debug > --verbose > --quiet Note: -v was not used for --verbose to avoid conflict with built-in --version flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): rename list --quiet to --ids-only Rename the --quiet flag to --ids-only to avoid conflict with the new global --quiet flag that controls verbosity. The --ids-only flag now only outputs instance IDs, one per line. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(output): add unit tests for output formatting package Add comprehensive unit tests for the pkg/output package covering: - ValidFormats() and IsValidFormat() validation functions - NewFormatter() with empty, valid, and invalid format inputs - Formatter.Format() accessor method - PrintJSON() with struct, map, and slice data types - PrintYAML() with struct, map, and nested struct data - Print() dispatch logic for JSON, YAML, and table formats - PrintTable() with mock TableData interface - TablePrinter fluent interface (Header, Row, Flush) - SetWriter() for output redirection - Error message quality for invalid formats Achieves 97.9% code coverage. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(output): add output formatting package with table/JSON/YAML support Adds pkg/output with Formatter, TablePrinter, and TableData interface for consistent output formatting across all CLI commands. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add output formatting to status command Adds -o flag (json/yaml/table) to holodeck status with structured output types for JSON/YAML serialization. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add describe, get, ssh, scp, update commands with tests New commands for issue NVIDIA#563: - describe: detailed instance introspection with JSON/YAML output - get kubeconfig: download kubeconfig from instance - get ssh-config: generate SSH config entry - ssh: SSH into instance or run remote commands - scp: copy files to/from instance via SFTP - update: update instance configuration (add components, labels) All commands include unit tests for core logic. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(list): update tests for --ids-only flag rename Updates list_test.go to use --ids-only instead of the old --quiet/-q flag which was renamed to avoid conflict with the global -q flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): fix nil map panic and SSH command quoting C1: Add nil check for env.Labels before writing provisioned label in update --reprovision. Previously panicked when no --label flags were provided and the cached environment had no labels. C2: Replace incorrect containsSpace+fmt.Sprintf("%q") quoting with simple strings.Join. SSH session.Run always passes through the remote shell, so Go-style quoting was wrong. Document this behavior. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract shared utilities and fix review issues - Extract getHostURL and connectSSH into cmd/cli/common package, eliminating duplication across ssh, scp, and get commands (I1) - Use path instead of filepath for remote SFTP paths to ensure correct POSIX separators on all platforms (I2) - Log warnings for skipped files during recursive remote copy (I3) - Use c.IsSet() for flags with defaults to prevent overwriting existing config with default values (I4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(ci): resolve lint issues, update go.mod, and remove plan docs - Fix gofmt, gosec, staticcheck, unconvert, and errcheck lint issues - Promote gopkg.in/yaml.v3 from indirect to direct dependency - Remove planning documents (development artifacts) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(security): correct misleading host key comments (CWE-322) Address CodeQL alert NVIDIA#6 (go/insecure-hostkeycallback) by replacing the inaccurate comment about "no pre-established host keys". The env file requires SSH authentication keys (client-to-server), but server host keys are a separate concern — they are generated at instance boot with no trusted distribution channel to the client. The security trade-off is now explicitly documented with CWE reference. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): use common.GetHostURL in update runProvision (S4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): consolidate update command cache file writes (C2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add -q as alias for --ids-only for backwards compatibility (S1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract SSH retry constants in ConnectSSH (S2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs(cli): document SSH remote command quoting behavior (S3) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): warnings always print regardless of verbosity (M1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): consolidate GetHostURL tests into common package (M3) Move duplicate GetHostURL tests from cmd/cli/get/ and cmd/cli/ssh/ into cmd/cli/common/host_test.go. Merge overlapping test cases and add a new TestGetHostURL_Cluster_FallbackToFirstNode case that covers the fallback path when no control-plane node exists. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): make Verbosity thread-safe with atomic.Int32 (M6) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): add nolint directive for gosec G115 in SetVerbosity Verbosity is an iota (0-3) so the int->int32 cast cannot overflow. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> --------- Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…A#621) * docs: add CLI CRUD and verbosity design document Design for issue NVIDIA#563 covering: - New CLI commands (describe, get, ssh, scp, update) - Global verbosity flags (-q, -v, -d) - Output formatting infrastructure - Implementation tasks and testing strategy Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs: add CLI CRUD implementation plan Detailed task-by-task implementation plan for: - Global verbosity flags (-q, -v, -d) - Unit tests for all new CLI commands - Output formatter tests 11 tasks with TDD approach and commit checkpoints. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(logger): add verbosity levels with Debug and Trace methods Add Verbosity type with four levels (Quiet, Normal, Verbose, Debug) to control log output. Info, Check, and Warning methods now respect verbosity settings, while Error always prints. New Debug and Trace methods provide additional logging granularity for troubleshooting. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add global verbosity flags (-q, --verbose, -d) Add global flags for controlling output verbosity: - --quiet, -q: Suppress non-error output - --verbose: Enable verbose output - --debug, -d: Enable debug-level logging (also reads DEBUG env var) Flag precedence: --debug > --verbose > --quiet Note: -v was not used for --verbose to avoid conflict with built-in --version flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): rename list --quiet to --ids-only Rename the --quiet flag to --ids-only to avoid conflict with the new global --quiet flag that controls verbosity. The --ids-only flag now only outputs instance IDs, one per line. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(output): add unit tests for output formatting package Add comprehensive unit tests for the pkg/output package covering: - ValidFormats() and IsValidFormat() validation functions - NewFormatter() with empty, valid, and invalid format inputs - Formatter.Format() accessor method - PrintJSON() with struct, map, and slice data types - PrintYAML() with struct, map, and nested struct data - Print() dispatch logic for JSON, YAML, and table formats - PrintTable() with mock TableData interface - TablePrinter fluent interface (Header, Row, Flush) - SetWriter() for output redirection - Error message quality for invalid formats Achieves 97.9% code coverage. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(output): add output formatting package with table/JSON/YAML support Adds pkg/output with Formatter, TablePrinter, and TableData interface for consistent output formatting across all CLI commands. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add output formatting to status command Adds -o flag (json/yaml/table) to holodeck status with structured output types for JSON/YAML serialization. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add describe, get, ssh, scp, update commands with tests New commands for issue NVIDIA#563: - describe: detailed instance introspection with JSON/YAML output - get kubeconfig: download kubeconfig from instance - get ssh-config: generate SSH config entry - ssh: SSH into instance or run remote commands - scp: copy files to/from instance via SFTP - update: update instance configuration (add components, labels) All commands include unit tests for core logic. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(list): update tests for --ids-only flag rename Updates list_test.go to use --ids-only instead of the old --quiet/-q flag which was renamed to avoid conflict with the global -q flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): fix nil map panic and SSH command quoting C1: Add nil check for env.Labels before writing provisioned label in update --reprovision. Previously panicked when no --label flags were provided and the cached environment had no labels. C2: Replace incorrect containsSpace+fmt.Sprintf("%q") quoting with simple strings.Join. SSH session.Run always passes through the remote shell, so Go-style quoting was wrong. Document this behavior. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract shared utilities and fix review issues - Extract getHostURL and connectSSH into cmd/cli/common package, eliminating duplication across ssh, scp, and get commands (I1) - Use path instead of filepath for remote SFTP paths to ensure correct POSIX separators on all platforms (I2) - Log warnings for skipped files during recursive remote copy (I3) - Use c.IsSet() for flags with defaults to prevent overwriting existing config with default values (I4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(ci): resolve lint issues, update go.mod, and remove plan docs - Fix gofmt, gosec, staticcheck, unconvert, and errcheck lint issues - Promote gopkg.in/yaml.v3 from indirect to direct dependency - Remove planning documents (development artifacts) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(security): correct misleading host key comments (CWE-322) Address CodeQL alert NVIDIA#6 (go/insecure-hostkeycallback) by replacing the inaccurate comment about "no pre-established host keys". The env file requires SSH authentication keys (client-to-server), but server host keys are a separate concern — they are generated at instance boot with no trusted distribution channel to the client. The security trade-off is now explicitly documented with CWE reference. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): use common.GetHostURL in update runProvision (S4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): consolidate update command cache file writes (C2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add -q as alias for --ids-only for backwards compatibility (S1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract SSH retry constants in ConnectSSH (S2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs(cli): document SSH remote command quoting behavior (S3) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): warnings always print regardless of verbosity (M1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): consolidate GetHostURL tests into common package (M3) Move duplicate GetHostURL tests from cmd/cli/get/ and cmd/cli/ssh/ into cmd/cli/common/host_test.go. Merge overlapping test cases and add a new TestGetHostURL_Cluster_FallbackToFirstNode case that covers the fallback path when no control-plane node exists. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): make Verbosity thread-safe with atomic.Int32 (M6) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): add nolint directive for gosec G115 in SetVerbosity Verbosity is an iota (0-3) so the int->int32 cast cannot overflow. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> --------- Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…A#621) * docs: add CLI CRUD and verbosity design document Design for issue NVIDIA#563 covering: - New CLI commands (describe, get, ssh, scp, update) - Global verbosity flags (-q, -v, -d) - Output formatting infrastructure - Implementation tasks and testing strategy Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs: add CLI CRUD implementation plan Detailed task-by-task implementation plan for: - Global verbosity flags (-q, -v, -d) - Unit tests for all new CLI commands - Output formatter tests 11 tasks with TDD approach and commit checkpoints. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(logger): add verbosity levels with Debug and Trace methods Add Verbosity type with four levels (Quiet, Normal, Verbose, Debug) to control log output. Info, Check, and Warning methods now respect verbosity settings, while Error always prints. New Debug and Trace methods provide additional logging granularity for troubleshooting. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add global verbosity flags (-q, --verbose, -d) Add global flags for controlling output verbosity: - --quiet, -q: Suppress non-error output - --verbose: Enable verbose output - --debug, -d: Enable debug-level logging (also reads DEBUG env var) Flag precedence: --debug > --verbose > --quiet Note: -v was not used for --verbose to avoid conflict with built-in --version flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): rename list --quiet to --ids-only Rename the --quiet flag to --ids-only to avoid conflict with the new global --quiet flag that controls verbosity. The --ids-only flag now only outputs instance IDs, one per line. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(output): add unit tests for output formatting package Add comprehensive unit tests for the pkg/output package covering: - ValidFormats() and IsValidFormat() validation functions - NewFormatter() with empty, valid, and invalid format inputs - Formatter.Format() accessor method - PrintJSON() with struct, map, and slice data types - PrintYAML() with struct, map, and nested struct data - Print() dispatch logic for JSON, YAML, and table formats - PrintTable() with mock TableData interface - TablePrinter fluent interface (Header, Row, Flush) - SetWriter() for output redirection - Error message quality for invalid formats Achieves 97.9% code coverage. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(output): add output formatting package with table/JSON/YAML support Adds pkg/output with Formatter, TablePrinter, and TableData interface for consistent output formatting across all CLI commands. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add output formatting to status command Adds -o flag (json/yaml/table) to holodeck status with structured output types for JSON/YAML serialization. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add describe, get, ssh, scp, update commands with tests New commands for issue NVIDIA#563: - describe: detailed instance introspection with JSON/YAML output - get kubeconfig: download kubeconfig from instance - get ssh-config: generate SSH config entry - ssh: SSH into instance or run remote commands - scp: copy files to/from instance via SFTP - update: update instance configuration (add components, labels) All commands include unit tests for core logic. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(list): update tests for --ids-only flag rename Updates list_test.go to use --ids-only instead of the old --quiet/-q flag which was renamed to avoid conflict with the global -q flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): fix nil map panic and SSH command quoting C1: Add nil check for env.Labels before writing provisioned label in update --reprovision. Previously panicked when no --label flags were provided and the cached environment had no labels. C2: Replace incorrect containsSpace+fmt.Sprintf("%q") quoting with simple strings.Join. SSH session.Run always passes through the remote shell, so Go-style quoting was wrong. Document this behavior. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract shared utilities and fix review issues - Extract getHostURL and connectSSH into cmd/cli/common package, eliminating duplication across ssh, scp, and get commands (I1) - Use path instead of filepath for remote SFTP paths to ensure correct POSIX separators on all platforms (I2) - Log warnings for skipped files during recursive remote copy (I3) - Use c.IsSet() for flags with defaults to prevent overwriting existing config with default values (I4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(ci): resolve lint issues, update go.mod, and remove plan docs - Fix gofmt, gosec, staticcheck, unconvert, and errcheck lint issues - Promote gopkg.in/yaml.v3 from indirect to direct dependency - Remove planning documents (development artifacts) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(security): correct misleading host key comments (CWE-322) Address CodeQL alert NVIDIA#6 (go/insecure-hostkeycallback) by replacing the inaccurate comment about "no pre-established host keys". The env file requires SSH authentication keys (client-to-server), but server host keys are a separate concern — they are generated at instance boot with no trusted distribution channel to the client. The security trade-off is now explicitly documented with CWE reference. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): use common.GetHostURL in update runProvision (S4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): consolidate update command cache file writes (C2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add -q as alias for --ids-only for backwards compatibility (S1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract SSH retry constants in ConnectSSH (S2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs(cli): document SSH remote command quoting behavior (S3) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): warnings always print regardless of verbosity (M1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): consolidate GetHostURL tests into common package (M3) Move duplicate GetHostURL tests from cmd/cli/get/ and cmd/cli/ssh/ into cmd/cli/common/host_test.go. Merge overlapping test cases and add a new TestGetHostURL_Cluster_FallbackToFirstNode case that covers the fallback path when no control-plane node exists. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): make Verbosity thread-safe with atomic.Int32 (M6) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): add nolint directive for gosec G115 in SetVerbosity Verbosity is an iota (0-3) so the int->int32 cast cannot overflow. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> --------- Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…A#621) * docs: add CLI CRUD and verbosity design document Design for issue NVIDIA#563 covering: - New CLI commands (describe, get, ssh, scp, update) - Global verbosity flags (-q, -v, -d) - Output formatting infrastructure - Implementation tasks and testing strategy Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs: add CLI CRUD implementation plan Detailed task-by-task implementation plan for: - Global verbosity flags (-q, -v, -d) - Unit tests for all new CLI commands - Output formatter tests 11 tasks with TDD approach and commit checkpoints. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(logger): add verbosity levels with Debug and Trace methods Add Verbosity type with four levels (Quiet, Normal, Verbose, Debug) to control log output. Info, Check, and Warning methods now respect verbosity settings, while Error always prints. New Debug and Trace methods provide additional logging granularity for troubleshooting. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add global verbosity flags (-q, --verbose, -d) Add global flags for controlling output verbosity: - --quiet, -q: Suppress non-error output - --verbose: Enable verbose output - --debug, -d: Enable debug-level logging (also reads DEBUG env var) Flag precedence: --debug > --verbose > --quiet Note: -v was not used for --verbose to avoid conflict with built-in --version flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): rename list --quiet to --ids-only Rename the --quiet flag to --ids-only to avoid conflict with the new global --quiet flag that controls verbosity. The --ids-only flag now only outputs instance IDs, one per line. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(output): add unit tests for output formatting package Add comprehensive unit tests for the pkg/output package covering: - ValidFormats() and IsValidFormat() validation functions - NewFormatter() with empty, valid, and invalid format inputs - Formatter.Format() accessor method - PrintJSON() with struct, map, and slice data types - PrintYAML() with struct, map, and nested struct data - Print() dispatch logic for JSON, YAML, and table formats - PrintTable() with mock TableData interface - TablePrinter fluent interface (Header, Row, Flush) - SetWriter() for output redirection - Error message quality for invalid formats Achieves 97.9% code coverage. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(output): add output formatting package with table/JSON/YAML support Adds pkg/output with Formatter, TablePrinter, and TableData interface for consistent output formatting across all CLI commands. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add output formatting to status command Adds -o flag (json/yaml/table) to holodeck status with structured output types for JSON/YAML serialization. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add describe, get, ssh, scp, update commands with tests New commands for issue NVIDIA#563: - describe: detailed instance introspection with JSON/YAML output - get kubeconfig: download kubeconfig from instance - get ssh-config: generate SSH config entry - ssh: SSH into instance or run remote commands - scp: copy files to/from instance via SFTP - update: update instance configuration (add components, labels) All commands include unit tests for core logic. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(list): update tests for --ids-only flag rename Updates list_test.go to use --ids-only instead of the old --quiet/-q flag which was renamed to avoid conflict with the global -q flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): fix nil map panic and SSH command quoting C1: Add nil check for env.Labels before writing provisioned label in update --reprovision. Previously panicked when no --label flags were provided and the cached environment had no labels. C2: Replace incorrect containsSpace+fmt.Sprintf("%q") quoting with simple strings.Join. SSH session.Run always passes through the remote shell, so Go-style quoting was wrong. Document this behavior. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract shared utilities and fix review issues - Extract getHostURL and connectSSH into cmd/cli/common package, eliminating duplication across ssh, scp, and get commands (I1) - Use path instead of filepath for remote SFTP paths to ensure correct POSIX separators on all platforms (I2) - Log warnings for skipped files during recursive remote copy (I3) - Use c.IsSet() for flags with defaults to prevent overwriting existing config with default values (I4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(ci): resolve lint issues, update go.mod, and remove plan docs - Fix gofmt, gosec, staticcheck, unconvert, and errcheck lint issues - Promote gopkg.in/yaml.v3 from indirect to direct dependency - Remove planning documents (development artifacts) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(security): correct misleading host key comments (CWE-322) Address CodeQL alert NVIDIA#6 (go/insecure-hostkeycallback) by replacing the inaccurate comment about "no pre-established host keys". The env file requires SSH authentication keys (client-to-server), but server host keys are a separate concern — they are generated at instance boot with no trusted distribution channel to the client. The security trade-off is now explicitly documented with CWE reference. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): use common.GetHostURL in update runProvision (S4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): consolidate update command cache file writes (C2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add -q as alias for --ids-only for backwards compatibility (S1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract SSH retry constants in ConnectSSH (S2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs(cli): document SSH remote command quoting behavior (S3) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): warnings always print regardless of verbosity (M1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): consolidate GetHostURL tests into common package (M3) Move duplicate GetHostURL tests from cmd/cli/get/ and cmd/cli/ssh/ into cmd/cli/common/host_test.go. Merge overlapping test cases and add a new TestGetHostURL_Cluster_FallbackToFirstNode case that covers the fallback path when no control-plane node exists. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): make Verbosity thread-safe with atomic.Int32 (M6) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): add nolint directive for gosec G115 in SetVerbosity Verbosity is an iota (0-3) so the int->int32 cast cannot overflow. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> --------- Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
…A#621) * docs: add CLI CRUD and verbosity design document Design for issue NVIDIA#563 covering: - New CLI commands (describe, get, ssh, scp, update) - Global verbosity flags (-q, -v, -d) - Output formatting infrastructure - Implementation tasks and testing strategy Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs: add CLI CRUD implementation plan Detailed task-by-task implementation plan for: - Global verbosity flags (-q, -v, -d) - Unit tests for all new CLI commands - Output formatter tests 11 tasks with TDD approach and commit checkpoints. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(logger): add verbosity levels with Debug and Trace methods Add Verbosity type with four levels (Quiet, Normal, Verbose, Debug) to control log output. Info, Check, and Warning methods now respect verbosity settings, while Error always prints. New Debug and Trace methods provide additional logging granularity for troubleshooting. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add global verbosity flags (-q, --verbose, -d) Add global flags for controlling output verbosity: - --quiet, -q: Suppress non-error output - --verbose: Enable verbose output - --debug, -d: Enable debug-level logging (also reads DEBUG env var) Flag precedence: --debug > --verbose > --quiet Note: -v was not used for --verbose to avoid conflict with built-in --version flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): rename list --quiet to --ids-only Rename the --quiet flag to --ids-only to avoid conflict with the new global --quiet flag that controls verbosity. The --ids-only flag now only outputs instance IDs, one per line. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(output): add unit tests for output formatting package Add comprehensive unit tests for the pkg/output package covering: - ValidFormats() and IsValidFormat() validation functions - NewFormatter() with empty, valid, and invalid format inputs - Formatter.Format() accessor method - PrintJSON() with struct, map, and slice data types - PrintYAML() with struct, map, and nested struct data - Print() dispatch logic for JSON, YAML, and table formats - PrintTable() with mock TableData interface - TablePrinter fluent interface (Header, Row, Flush) - SetWriter() for output redirection - Error message quality for invalid formats Achieves 97.9% code coverage. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(output): add output formatting package with table/JSON/YAML support Adds pkg/output with Formatter, TablePrinter, and TableData interface for consistent output formatting across all CLI commands. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add output formatting to status command Adds -o flag (json/yaml/table) to holodeck status with structured output types for JSON/YAML serialization. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add describe, get, ssh, scp, update commands with tests New commands for issue NVIDIA#563: - describe: detailed instance introspection with JSON/YAML output - get kubeconfig: download kubeconfig from instance - get ssh-config: generate SSH config entry - ssh: SSH into instance or run remote commands - scp: copy files to/from instance via SFTP - update: update instance configuration (add components, labels) All commands include unit tests for core logic. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * test(list): update tests for --ids-only flag rename Updates list_test.go to use --ids-only instead of the old --quiet/-q flag which was renamed to avoid conflict with the global -q flag. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): fix nil map panic and SSH command quoting C1: Add nil check for env.Labels before writing provisioned label in update --reprovision. Previously panicked when no --label flags were provided and the cached environment had no labels. C2: Replace incorrect containsSpace+fmt.Sprintf("%q") quoting with simple strings.Join. SSH session.Run always passes through the remote shell, so Go-style quoting was wrong. Document this behavior. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract shared utilities and fix review issues - Extract getHostURL and connectSSH into cmd/cli/common package, eliminating duplication across ssh, scp, and get commands (I1) - Use path instead of filepath for remote SFTP paths to ensure correct POSIX separators on all platforms (I2) - Log warnings for skipped files during recursive remote copy (I3) - Use c.IsSet() for flags with defaults to prevent overwriting existing config with default values (I4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(ci): resolve lint issues, update go.mod, and remove plan docs - Fix gofmt, gosec, staticcheck, unconvert, and errcheck lint issues - Promote gopkg.in/yaml.v3 from indirect to direct dependency - Remove planning documents (development artifacts) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(security): correct misleading host key comments (CWE-322) Address CodeQL alert NVIDIA#6 (go/insecure-hostkeycallback) by replacing the inaccurate comment about "no pre-established host keys". The env file requires SSH authentication keys (client-to-server), but server host keys are a separate concern — they are generated at instance boot with no trusted distribution channel to the client. The security trade-off is now explicitly documented with CWE reference. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): use common.GetHostURL in update runProvision (S4) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(cli): consolidate update command cache file writes (C2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * feat(cli): add -q as alias for --ids-only for backwards compatibility (S1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): extract SSH retry constants in ConnectSSH (S2) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * docs(cli): document SSH remote command quoting behavior (S3) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): warnings always print regardless of verbosity (M1) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * refactor(cli): consolidate GetHostURL tests into common package (M3) Move duplicate GetHostURL tests from cmd/cli/get/ and cmd/cli/ssh/ into cmd/cli/common/host_test.go. Merge overlapping test cases and add a new TestGetHostURL_Cluster_FallbackToFirstNode case that covers the fallback path when no control-plane node exists. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): make Verbosity thread-safe with atomic.Int32 (M6) Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> * fix(logger): add nolint directive for gosec G115 in SetVerbosity Verbosity is an iota (0-3) so the int->int32 cast cannot overflow. Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com> --------- Signed-off-by: Carlos Eduardo Arango Gutierrez <eduardoa@nvidia.com>
Summary
Implements the complete CLI CRUD operations epic (#563) to unblock 11 dependent PRs. This adds:
-q,--verbose,-dflagspkg/outputpackagedescribe,get kubeconfig,get ssh-config,ssh,scp,updatelist: renamed--quietto--ids-onlyfor claritycmd/cli/commonpackage withGetHostURLandConnectSSH--outputflagKey changes
internal/logger/logger.go— verbosity levels (Quiet/Normal/Verbose/Debug)pkg/output/output.go— Formatter, TablePrinter, TableData interfacecmd/cli/common/host.go— shared host URL resolution and SSH connectioncmd/cli/describe/— detailed instance info with JSON/YAML/table outputcmd/cli/get/— kubeconfig download and SSH config generationcmd/cli/ssh/— interactive SSH and remote command executioncmd/cli/scp/— SFTP file transfer with recursive directory supportcmd/cli/update/— add components, labels, and re-provision instancesReview fixes included
--reprovisioncontainsSpacelogic)getHostURL/connectSSHinto sharedcommonpackagepath(POSIX) for remote SFTP paths instead offilepathc.IsSet()for flags with defaults to prevent config overwritesTest plan
go test ./cmd/cli/...)pkg/output)GetHostURLacross ssh, get, and common packagesparsePath,describe,update, and label handlingholodeck list,holodeck describe <id>,holodeck ssh <id>holodeck scp ./file <id>:/tmp/,holodeck get kubeconfig <id>holodeck update <id> --add-driver --driver-version 560.35.03Closes #563