Documentation ¶
Overview ¶
Package cli facilitates building command-line applications for sending commands to vehicles. It defines a Config type that can be used to register common command-line flags (using the Golang flag package) and environment variable equivalents.
The package uses keyring's platform-agnostic interface for storing sensitive values (private keys and OAuth tokens) in an OS-dependent credential store.
Examples ¶
import flag config, err := NewConfig(FlagAll) if err != nil { panic(err) } config.RegisterCommandLineFlags() // Adds command-line flags for private keys, OAuth, etc. flag.Parse() config.ReadFromEnvironment() // Fills in missing fields using environment variables config.LoadCredentials() // Prompt for Keyring password if needed // Initializes car and acct if relevant fields are populated (from a combination of command-line // flags and environment variables). The car and acct may be nil even if error is nil. The car // connection might be over BLE or over the Internet. car, acct, err := config.Connect() if err != nil { panic(err) } defer config.UpdateCachedSessions()
You can also specify the connection type (which will then fail if the necessary fields are unpopulated):
car, err = config.ConnectRemote() // Connect to a car over the Internet. car, err = config.ConnectLocal() // Connect to a car over BLE.
Alternatively, you can use a Flag mask to control what Config fields are populated. Note that in the examples below, config.Flags must be set before calling flag.Parse or Config.ReadFromEnvironment:
config, err = NewConfig(FlagOAuth | FlagPrivateKey | FlagVIN) // config.Connect() will use the Internet, not BLE. config, err = NewConfig(FlagBLE | FlagPrivateKey | FlagVIN) // config.Connect() will use BLE, not the Internet. config, err = NewConfig(FlagBLE | FlagVIN) // config.Connect() will create an unauthenticated vehicle connection.
The last option will not attempt to load private keys when calling Config.Connect, and therefore will not result in an error if a private key is defined in the environment but cannot be loaded. However, most vehicle.Vehicle commands do not work over unauthenticated connections.
Index ¶
- Constants
- Variables
- type Config
- func (c *Config) Account() (*account.Account, error)
- func (c *Config) Connect(ctx context.Context) (acct *account.Account, car *vehicle.Vehicle, err error)
- func (c *Config) ConnectLocal(ctx context.Context, skey protocol.ECDHPrivateKey) (car *vehicle.Vehicle, err error)
- func (c *Config) ConnectRemote(ctx context.Context, skey protocol.ECDHPrivateKey) (acct *account.Account, car *vehicle.Vehicle, err error)
- func (c *Config) DeletePrivateKey() error
- func (c *Config) LoadCredentials() error
- func (c *Config) LoadKeyFromKeyring() (protocol.ECDHPrivateKey, error)
- func (c *Config) LoadTokenFromKeyring() (string, error)
- func (c *Config) PrivateKey() (skey protocol.ECDHPrivateKey, err error)
- func (c *Config) ReadFromEnvironment()
- func (c *Config) RegisterCommandLineFlags()
- func (c *Config) SavePrivateKey(skey protocol.ECDHPrivateKey) error
- func (c *Config) SaveTokenToKeyring(token string) error
- func (c *Config) UpdateCachedSessions(v *vehicle.Vehicle)
- type DomainList
- type Flag
Constants ¶
const ( EnvTeslaKeyName = "TESLA_KEY_NAME" EnvTeslaKeyFile = "TESLA_KEY_FILE" EnvTeslaTokenName = "TESLA_TOKEN_NAME" EnvTeslaTokenFile = "TESLA_TOKEN_FILE" EnvTeslaVIN = "TESLA_VIN" EnvTeslaCacheFile = "TESLA_CACHE_FILE" EnvTeslaKeyringType = "TESLA_KEYRING_TYPE" EnvTeslaKeyringPass = "TESLA_KEYRING_PASSWORD" EnvTeslaKeyringPath = "TESLA_KEYRING_PATH" EnvTeslaKeyringDebug = "TESLA_KEYRING_DEBUG" )
Environment variable names used are used by Config.ReadFromEnvironment to set common parameters.
Variables ¶
var ( ErrNoKeySpecified = errors.New("private key location not provided") ErrNoAvailableTransports = errors.New("no available transports (configuration must permit BLE and/or OAuth)") ErrKeyNotFound = keyring.ErrKeyNotFound )
var DomainNames = map[protocol.Domain]string{ protocol.DomainVCSEC: "VCSEC", protocol.DomainInfotainment: "INFOTAINMENT", }
var DomainsByName = map[string]protocol.Domain{ "VCSEC": protocol.DomainVCSEC, "INFOTAINMENT": protocol.DomainInfotainment, }
Functions ¶
This section is empty.
Types ¶
type Config ¶
type Config struct { Flags Flag // Controls which set of environment variables/CLI flags to use. KeyringKeyName string // Username for private key in system keyring KeyringTokenName string // Username for OAuth token in system keyring VIN string TokenFilename string KeyFilename string CacheFilename string Backend keyring.Config BackendType backendType Debug bool // Enable keyring debug messages // Domains can limit a vehicle connection to relevant subsystems, which can reduce // connection latency and avoid waking up the infotainment system unnecessarily. Domains DomainList // contains filtered or unexported fields }
Config fields determine how a client authenticates to vehicles and/or Tesla's backend.
func (*Config) Connect ¶
func (c *Config) Connect(ctx context.Context) (acct *account.Account, car *vehicle.Vehicle, err error)
Connect to vehicle and/or account.
If c.TokenFilename is set, the returned account will not be nil and the vehicle will use a connector.inet connection if a VIN was provided. If no token filename is set, c.VIN is required, the account will be nil, and the vehicle will use a connector.ble connection.
func (*Config) ConnectLocal ¶
func (c *Config) ConnectLocal(ctx context.Context, skey protocol.ECDHPrivateKey) (car *vehicle.Vehicle, err error)
ConnectLocal connects to a vehicle over BLE.
func (*Config) ConnectRemote ¶
func (c *Config) ConnectRemote(ctx context.Context, skey protocol.ECDHPrivateKey) (acct *account.Account, car *vehicle.Vehicle, err error)
ConnectRemote logs in to the configured Tesla account, and, if c includes a VIN, also fetches the corresponding vehicle.
func (*Config) DeletePrivateKey ¶
DeletePrivateKey removes the private key from the system keyring.
func (*Config) LoadCredentials ¶
LoadCredentials attempts to open a keyring, prompting for a password if not needed. Call this method before [config.Connect] to prevent interactive prompts from counting against timeouts.
func (*Config) LoadKeyFromKeyring ¶
func (c *Config) LoadKeyFromKeyring() (protocol.ECDHPrivateKey, error)
LoadKeyFromKeyring reads a private key from the system keyring.
The provided name is an arbitrary string that identifies the key.
func (*Config) LoadTokenFromKeyring ¶
LoadTokenFromKeyring loads an OAuth token from the system keyring.
The user must match the value provided to SaveTokenToKeyring.
func (*Config) PrivateKey ¶
func (c *Config) PrivateKey() (skey protocol.ECDHPrivateKey, err error)
PrivateKey loads a private key from the location specified in c.
If c does not specify a private key location, both skey and err will be nil. The private key is cached after it is first loaded, and subsequent calls will always return the same private key.
func (*Config) ReadFromEnvironment ¶
func (c *Config) ReadFromEnvironment()
ReadFromEnvironment populates c using environment variables. Values that are already populated are not overwritten.
Calling ReadFromEnvironment after flag.Parse() (or other initialization method) will prevent the environment from overriding explicit command-line parameters and avoid potentially misleading debug log messages.
func (*Config) RegisterCommandLineFlags ¶
func (c *Config) RegisterCommandLineFlags()
func (*Config) SavePrivateKey ¶
func (c *Config) SavePrivateKey(skey protocol.ECDHPrivateKey) error
SavePrivateKey writes skey to the system keyring or file, depending on what options are configured. The method prefers the keyring if both options are available.
func (*Config) SaveTokenToKeyring ¶
SaveTokenToKeyring writes the account's OAuth token to the system keyring.
The user identifies the OAuth token for future use with account.LoadTokenFromKeyring and does not necessarily need to match the system username.
func (*Config) UpdateCachedSessions ¶
UpdateCachedSessions updates c.CacheFilename with updated session state.
If c.CacheFilename is not set or no vehicle handshake has occurred, then this method does nothing.
type DomainList ¶ added in v0.1.0
DomainList is used to translate domains provided at the command line into native protocol.Domain values.
func (*DomainList) Set ¶ added in v0.1.0
func (d *DomainList) Set(value string) error
Set updates a DomainList from a command-line argument.
func (*DomainList) String ¶ added in v0.1.0
func (d *DomainList) String() string
type Flag ¶
type Flag int
Flag controls what options should be scanned from the command line and/or environment variables.
const ( FlagVIN Flag = 1 // Enable VIN option. FlagOAuth Flag = 2 // Enable OAuth options. FlagPrivateKey Flag = 4 // Enable Private Key options. Required for sending vehicle commands. FlagBLE Flag = 8 // Enable BLE options. Requires FlagVIN. FlagAll Flag = FlagVIN | FlagOAuth | FlagPrivateKey | FlagBLE )