mirror of
https://github.com/coder/coder.git
synced 2025-07-08 11:39:50 +00:00
feat: Add deployment side config-ssh options (#6613)
* feat: Allow setting deployment wide ssh config settings * feat: config-ssh respects deployment ssh config * The '.' is now configurable * Move buildinfo into deployment.go
This commit is contained in:
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"flag"
|
||||
"fmt"
|
||||
"math"
|
||||
"net/http"
|
||||
"os"
|
||||
@ -160,6 +161,7 @@ type DeploymentValues struct {
|
||||
DisablePasswordAuth clibase.Bool `json:"disable_password_auth,omitempty" typescript:",notnull"`
|
||||
Support SupportConfig `json:"support,omitempty" typescript:",notnull"`
|
||||
GitAuthProviders clibase.Struct[[]GitAuthConfig] `json:"git_auth,omitempty" typescript:",notnull"`
|
||||
SSHConfig SSHConfig `json:"config_ssh,omitempty" typescript:",notnull"`
|
||||
|
||||
Config clibase.String `json:"config,omitempty" typescript:",notnull"`
|
||||
WriteConfig clibase.Bool `json:"write_config,omitempty" typescript:",notnull"`
|
||||
@ -168,6 +170,40 @@ type DeploymentValues struct {
|
||||
Address clibase.HostPort `json:"address,omitempty" typescript:",notnull"`
|
||||
}
|
||||
|
||||
// SSHConfig is configuration the cli & vscode extension use for configuring
|
||||
// ssh connections.
|
||||
type SSHConfig struct {
|
||||
// DeploymentName is the config-ssh Hostname prefix
|
||||
DeploymentName clibase.String
|
||||
// SSHConfigOptions are additional options to add to the ssh config file.
|
||||
// This will override defaults.
|
||||
SSHConfigOptions clibase.Strings
|
||||
}
|
||||
|
||||
func (c SSHConfig) ParseOptions() (map[string]string, error) {
|
||||
m := make(map[string]string)
|
||||
for _, opt := range c.SSHConfigOptions {
|
||||
key, value, err := ParseSSHConfigOption(opt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
m[key] = value
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
||||
// ParseSSHConfigOption parses a single ssh config option into it's key/value pair.
|
||||
func ParseSSHConfigOption(opt string) (key string, value string, err error) {
|
||||
// An equal sign or whitespace is the separator between the key and value.
|
||||
idx := strings.IndexFunc(opt, func(r rune) bool {
|
||||
return r == ' ' || r == '='
|
||||
})
|
||||
if idx == -1 {
|
||||
return "", "", fmt.Errorf("invalid config-ssh option %q", opt)
|
||||
}
|
||||
return opt[:idx], opt[idx+1:], nil
|
||||
}
|
||||
|
||||
type DERP struct {
|
||||
Server DERPServerConfig `json:"server" typescript:",notnull"`
|
||||
Config DERPConfig `json:"config" typescript:",notnull"`
|
||||
@ -390,6 +426,11 @@ when required by your organization's security policy.`,
|
||||
deploymentGroupDangerous = clibase.Group{
|
||||
Name: "⚠️ Dangerous",
|
||||
}
|
||||
deploymentGroupClient = clibase.Group{
|
||||
Name: "Client",
|
||||
Description: "These options change the behavior of how clients interact with the Coder. " +
|
||||
"Clients include the coder cli, vs code extension, and the web UI.",
|
||||
}
|
||||
deploymentGroupConfig = clibase.Group{
|
||||
Name: "Config",
|
||||
Description: `Use a YAML configuration file when your server launch become unwieldy.`,
|
||||
@ -1265,6 +1306,29 @@ when required by your organization's security policy.`,
|
||||
Group: &deploymentGroupConfig,
|
||||
Value: &c.Config,
|
||||
},
|
||||
{
|
||||
Name: "SSH Host Prefix",
|
||||
Description: "The SSH deployment prefix is used in the Host of the ssh config.",
|
||||
Flag: "ssh-hostname-prefix",
|
||||
Env: "SSH_HOSTNAME_PREFIX",
|
||||
YAML: "sshHostnamePrefix",
|
||||
Group: &deploymentGroupClient,
|
||||
Value: &c.SSHConfig.DeploymentName,
|
||||
Hidden: false,
|
||||
Default: "coder.",
|
||||
},
|
||||
{
|
||||
Name: "SSH Config Options",
|
||||
Description: "These SSH config options will override the default SSH config options. " +
|
||||
"Provide options in \"key=value\" or \"key value\" format separated by commas." +
|
||||
"Using this incorrectly can break SSH to your deployment, use cautiously.",
|
||||
Flag: "ssh-config-options",
|
||||
Env: "SSH_CONFIG_OPTIONS",
|
||||
YAML: "sshConfigOptions",
|
||||
Group: &deploymentGroupClient,
|
||||
Value: &c.SSHConfig.SSHConfigOptions,
|
||||
Hidden: false,
|
||||
},
|
||||
{
|
||||
Name: "Write Config",
|
||||
Description: `
|
||||
@ -1580,3 +1644,25 @@ type DeploymentStats struct {
|
||||
Workspaces WorkspaceDeploymentStats `json:"workspaces"`
|
||||
SessionCount SessionCountDeploymentStats `json:"session_count"`
|
||||
}
|
||||
|
||||
type SSHConfigResponse struct {
|
||||
HostnamePrefix string `json:"hostname_prefix"`
|
||||
SSHConfigOptions map[string]string `json:"ssh_config_options"`
|
||||
}
|
||||
|
||||
// SSHConfiguration returns information about the SSH configuration for the
|
||||
// Coder instance.
|
||||
func (c *Client) SSHConfiguration(ctx context.Context) (SSHConfigResponse, error) {
|
||||
res, err := c.Request(ctx, http.MethodGet, "/api/v2/deployment/ssh", nil)
|
||||
if err != nil {
|
||||
return SSHConfigResponse{}, err
|
||||
}
|
||||
defer res.Body.Close()
|
||||
|
||||
if res.StatusCode != http.StatusOK {
|
||||
return SSHConfigResponse{}, ReadBodyAsError(res)
|
||||
}
|
||||
|
||||
var sshConfig SSHConfigResponse
|
||||
return sshConfig, json.NewDecoder(res.Body).Decode(&sshConfig)
|
||||
}
|
||||
|
Reference in New Issue
Block a user