mirror of
https://github.com/gravitational/teleport.git
synced 2026-10-12 02:15:01 +00:00
tctl devices add: Derive --os flag from devicepb.OSType (#69136)
* `tctl devices add`: Derive `--os` flag from `devicepb.OSType` * Base accepted `--os` values on the api layer
This commit is contained in:
@@ -1469,7 +1469,7 @@ Flags:
|
||||
|`--format`|`text` (one of: `text`, `json`, `yaml`)|Output format.|
|
||||
|`--[no-]current-device`|`false`|Registers the current device. Overrides --os and --asset-tag.|
|
||||
|`--[no-]enroll`|`false`|If set, creates a device enrollment token|
|
||||
|`--os`|*no default* (one of: `linux`, `macos`, `windows`)|Operating system|
|
||||
|`--os`|*no default* (one of: `ios`, `ipados`, `linux`, `macos`, `windows`)|Operating system|
|
||||
|
||||
## tctl devices enroll
|
||||
|
||||
|
||||
+21
-19
@@ -62,20 +62,19 @@ type DevicesCommand struct {
|
||||
Stdout io.Writer
|
||||
}
|
||||
|
||||
type osType = string
|
||||
|
||||
const (
|
||||
linuxType osType = "linux"
|
||||
macosType osType = "macos"
|
||||
windowsType osType = "windows"
|
||||
)
|
||||
|
||||
var osTypes = []string{linuxType, macosType, windowsType}
|
||||
|
||||
var osTypeToEnum = map[osType]devicepb.OSType{
|
||||
linuxType: devicepb.OSType_OS_TYPE_LINUX,
|
||||
macosType: devicepb.OSType_OS_TYPE_MACOS,
|
||||
windowsType: devicepb.OSType_OS_TYPE_WINDOWS,
|
||||
// osTypeFlagValues returns the accepted --os values: every [devicepb.OSType]
|
||||
// except UNSPECIFIED, spelled the way api spells it.
|
||||
func osTypeFlagValues() []string {
|
||||
values := make([]string, 0, len(devicepb.OSType_name)-1)
|
||||
for num := range devicepb.OSType_name {
|
||||
osType := devicepb.OSType(num)
|
||||
if osType == devicepb.OSType_OS_TYPE_UNSPECIFIED {
|
||||
continue
|
||||
}
|
||||
values = append(values, types.ResourceOSTypeToString(osType))
|
||||
}
|
||||
sort.Strings(values)
|
||||
return values
|
||||
}
|
||||
|
||||
func (c *DevicesCommand) Initialize(app *kingpin.Application, _ *tctlcfg.GlobalCLIFlags, cfg *servicecfg.Config) {
|
||||
@@ -85,7 +84,7 @@ func (c *DevicesCommand) Initialize(app *kingpin.Application, _ *tctlcfg.GlobalC
|
||||
|
||||
addCmd := devicesCmd.Command("add", "Register managed devices.")
|
||||
addCmd.Flag("os", "Operating system").
|
||||
EnumVar(&c.add.os, osTypes...)
|
||||
EnumVar(&c.add.os, osTypeFlagValues()...)
|
||||
addCmd.Flag("asset-tag", "Inventory identifier for the device (e.g., Mac serial number)").
|
||||
StringVar(&c.add.assetTag)
|
||||
addCmd.Flag("current-device", "Registers the current device. Overrides --os and --asset-tag.").
|
||||
@@ -193,10 +192,13 @@ func (c *deviceAddCommand) Run(ctx context.Context, authClient *authclient.Clien
|
||||
}
|
||||
|
||||
if c.os != "" {
|
||||
var ok bool
|
||||
c.osType, ok = osTypeToEnum[c.os]
|
||||
if !ok {
|
||||
return trace.BadParameter("invalid --os: %v", c.os)
|
||||
var err error
|
||||
// kingpin makes sure that c.os is set to one of the values returned from
|
||||
// [osTypeFlagValues], so we don't have to worry about "unspecified" here.
|
||||
if c.osType, err = types.ResourceOSTypeFromString(c.os); err != nil {
|
||||
// No need to re-wrap err into something specific to the --os flag, as at
|
||||
// this point we know that c.os points to a valid OSType.
|
||||
return trace.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -22,12 +22,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gravitational/trace"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
|
||||
"github.com/gravitational/teleport"
|
||||
devicepb "github.com/gravitational/teleport/api/gen/proto/go/teleport/devicetrust/v1"
|
||||
"github.com/gravitational/teleport/api/types"
|
||||
"github.com/gravitational/teleport/lib/service/servicecfg"
|
||||
"github.com/gravitational/teleport/lib/utils"
|
||||
tctlcfg "github.com/gravitational/teleport/tool/tctl/common/config"
|
||||
)
|
||||
|
||||
func TestDeviceSourceToString(t *testing.T) {
|
||||
@@ -148,3 +152,41 @@ func TestWriteCreatedLock(t *testing.T) {
|
||||
require.True(t, trace.IsBadParameter(err), "expected BadParameter, got %v", err)
|
||||
})
|
||||
}
|
||||
|
||||
// TestOSTypeFlagValues covers the --os values offered by `tctl devices add`.
|
||||
// They come from devicepb.OSType, so an OSType that ResourceOSTypeToString
|
||||
// doesn't know about would reach the CLI as its bare proto name.
|
||||
func TestOSTypeFlagValues(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
require.Equal(t, []string{"ios", "ipados", "linux", "macos", "windows"},
|
||||
osTypeFlagValues(), "osTypeFlagValues mismatch")
|
||||
}
|
||||
|
||||
// TestDeviceAddOSFlag covers the --os values `tctl devices add` accepts.
|
||||
// The flag is the only thing keeping UNSPECIFIED out, as
|
||||
// [types.ResourceOSTypeFromString] resolves "unspecified" without an error.
|
||||
func TestDeviceAddOSFlag(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
parse := func(t *testing.T, os string) error {
|
||||
t.Helper()
|
||||
c := DevicesCommand{}
|
||||
app := utils.InitCLIParser("tctl", GlobalHelpString)
|
||||
c.Initialize(app, &tctlcfg.GlobalCLIFlags{}, servicecfg.MakeDefaultConfig())
|
||||
_, err := app.Parse([]string{"devices", "add", "--os", os, "--asset-tag", "C00AA0AAAA0A"})
|
||||
return err
|
||||
}
|
||||
|
||||
for _, os := range osTypeFlagValues() {
|
||||
t.Run(os, func(t *testing.T) {
|
||||
assert.NoError(t, parse(t, os), "--os %v rejected", os)
|
||||
})
|
||||
}
|
||||
|
||||
for _, os := range []string{"unspecified", "OS_TYPE_MACOS", "bogus"} {
|
||||
t.Run("rejects "+os, func(t *testing.T) {
|
||||
assert.ErrorContains(t, parse(t, os), "enum value must be one of ios,", "--os %v accepted", os)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user