Skip to content

feat: Add deployment side config-ssh options #6613

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

Merged
merged 34 commits into from
Mar 16, 2023
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
79535d0
feat: Allow setting deployment wide ssh config settings
Emyrk Mar 14, 2023
f0eb123
feat: config-ssh respects deployment ssh config
Emyrk Mar 15, 2023
4beeb62
Catch early parse error
Emyrk Mar 15, 2023
08f5d3d
Add to unit test
Emyrk Mar 15, 2023
c8c5189
fix typo
Emyrk Mar 15, 2023
96ad4bc
Add unit test
Emyrk Mar 15, 2023
f9f4a8f
Fix output
Emyrk Mar 15, 2023
ebf9eb9
Make gen
Emyrk Mar 15, 2023
119695b
Simplify if/else
Emyrk Mar 15, 2023
b8f3242
Fix AutorizeAllEndpoints
Emyrk Mar 15, 2023
b082a5a
Fic swager docs
Emyrk Mar 15, 2023
4a1e3c2
Make gen
Emyrk Mar 15, 2023
01ea08f
The '.' is now configurable
Emyrk Mar 15, 2023
7074f50
CODER env prefix is automatic
Emyrk Mar 15, 2023
952c591
Renames
Emyrk Mar 15, 2023
dae091a
Make gen
Emyrk Mar 15, 2023
a1dd7d4
Fix AutorizeAllEndpoints
Emyrk Mar 15, 2023
4f42634
Rename to drop 'CLI'
Emyrk Mar 15, 2023
c218edd
Prefix requires .
Emyrk Mar 15, 2023
a752fc8
Use constant in test
Emyrk Mar 15, 2023
d328d97
Linting
Emyrk Mar 15, 2023
a4b9620
Formatting
Emyrk Mar 15, 2023
78fbda8
Allow the user to override the host prefix
Emyrk Mar 16, 2023
d28b850
Fix doc messages
Emyrk Mar 16, 2023
617d987
Make gen
Emyrk Mar 16, 2023
eb4bb7b
Fix comment
Emyrk Mar 16, 2023
123ce02
Remove "CLI" part of naming
Emyrk Mar 16, 2023
ca41cce
Update golden files
Emyrk Mar 16, 2023
efcbc29
Fix 404 logic
Emyrk Mar 16, 2023
3c1c87f
remove 1 error check
Emyrk Mar 16, 2023
4586b11
Move buildinfo into deployment.go
Emyrk Mar 16, 2023
0f2ef97
fixup! Move buildinfo into deployment.go
Emyrk Mar 16, 2023
a5aac50
make gen
Emyrk Mar 16, 2023
a3254cd
Golden files
Emyrk Mar 16, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat: Allow setting deployment wide ssh config settings
  • Loading branch information
Emyrk committed Mar 14, 2023
commit 79535d0435c41d71b0928d32b712a00d040b6af1
9 changes: 9 additions & 0 deletions cli/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,11 @@ flags, and YAML configuration. The precedence is as follows:
return xerrors.Errorf("parse real ip config: %w", err)
}

configSSHOptions, err := cfg.CLISSH.ParseOptions()
if err != nil {
return xerrors.Errorf("parse ssh config options \"%v\" %w", cfg.CLISSH.SSHConfigOptions, err)
}

options := &coderd.Options{
AccessURL: cfg.AccessURL.Value(),
AppHostname: appHostname,
Expand All @@ -696,6 +701,10 @@ flags, and YAML configuration. The precedence is as follows:
LoginRateLimit: loginRateLimit,
FilesRateLimit: filesRateLimit,
HTTPClient: httpClient,
ConfigSSH: codersdk.CLISSHConfigResponse{
DeploymentName: cfg.CLISSH.DeploymentName.String(),
SSHConfigOptions: configSSHOptions,
},
}
if tlsConfig != nil {
options.TLSCertificates = tlsConfig.Certificates
Expand Down
17 changes: 17 additions & 0 deletions coderd/clissh.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package coderd

import (
"net/http"

"github.com/coder/coder/coderd/httpapi"
)

// @Summary SSH information for clients
// @ID cli-ssh-config
// @Produce json
// @Tags General
// @Success 200 {object} codersdk.BuildInfoResponse
// @Router /ssh-config [get]
func (a *API) cliSSHConfig(rw http.ResponseWriter, r *http.Request) {
httpapi.Write(r.Context(), rw, http.StatusOK, a.ConfigSSH)
}
10 changes: 10 additions & 0 deletions coderd/coderd.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,9 @@ type Options struct {
DeploymentValues *codersdk.DeploymentValues
UpdateCheckOptions *updatecheck.Options // Set non-nil to enable update checking.

// ConfigSSH is the response clients use to configure config-ssh locally.
ConfigSSH codersdk.CLISSHConfigResponse

HTTPClient *http.Client
}

Expand Down Expand Up @@ -399,6 +402,13 @@ func New(options *Options) *API {
r.Post("/csp/reports", api.logReportCSPViolations)

r.Get("/buildinfo", buildInfo)
r.Route("/ssh-config", func(r chi.Router) {
// Require auth for this route to prevent leaking the SSH config.
// to non-authenticated users. Also some config settings might
// be dependent on the user.
r.Use(apiKeyMiddleware)
r.Get("/", api.cliSSHConfig)
})
r.Route("/deployment", func(r chi.Router) {
r.Use(apiKeyMiddleware)
r.Get("/config", api.deploymentValues)
Expand Down
76 changes: 76 additions & 0 deletions codersdk/deployment.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"encoding/json"
"flag"
"fmt"
"math"
"net/http"
"os"
Expand Down Expand Up @@ -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"`
CLISSH CLISSHConfig `json:"cli_ssh,omitempty" typescript:",notnull"`

Config clibase.String `json:"config,omitempty" typescript:",notnull"`
WriteConfig clibase.Bool `json:"write_config,omitempty" typescript:",notnull"`
Expand All @@ -168,6 +170,30 @@ type DeploymentValues struct {
Address clibase.HostPort `json:"address,omitempty" typescript:",notnull"`
}

// CLISSHConfig is configuration the cli & vscode extension use for configuring
// ssh connections.
type CLISSHConfig 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 CLISSHConfig) ParseOptions() (map[string]string, error) {
m := make(map[string]string)
for _, opt := range c.SSHConfigOptions {
// Only split once, the value could contain an equals sign.
// The key should never, so this is safe.
parts := strings.SplitN(opt, "=", 1)
if len(parts) != 2 {
return nil, fmt.Errorf("invalid config-ssh option %q", opt)
}
m[parts[0]] = parts[1]
}
return m, nil
}

type DERP struct {
Server DERPServerConfig `json:"server" typescript:",notnull"`
Config DERPConfig `json:"config" typescript:",notnull"`
Expand Down Expand Up @@ -390,6 +416,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.`,
Expand Down Expand Up @@ -1265,6 +1296,29 @@ when required by your organization's security policy.`,
Group: &deploymentGroupConfig,
Value: &c.Config,
},
{
Name: "CLI SSH Deployment Name",
Description: "The CLI SSH deployment name is the used in the Hostname of the ssh config.",
Flag: "cli-ssh-deployment-name",
Env: "CLI_SSH_DEPLOYMENT_NAME",
YAML: "cliSSHDeploymentName",
Group: &deploymentGroupClient,
Value: &c.CLISSH.DeploymentName,
Hidden: false,
Default: "coder",
},
{
Name: "CLI SSH Config Options",
Description: "These cli config options will override the default ssh config options. " +
"Provide options in key=value format seperated by commas." +
"Using this incorrectly can break ssh to your deployment. Use cautiously.",
Flag: "cli-ssh-options",
Env: "CLI_SSH_OPTIONS",
YAML: "cliSSHOptions",
Group: &deploymentGroupClient,
Value: &c.CLISSH.SSHConfigOptions,
Hidden: false,
},
{
Name: "Write Config",
Description: `
Expand Down Expand Up @@ -1580,3 +1634,25 @@ type DeploymentStats struct {
Workspaces WorkspaceDeploymentStats `json:"workspaces"`
SessionCount SessionCountDeploymentStats `json:"session_count"`
}

type CLISSHConfigResponse struct {
DeploymentName string `json:"deployment_name"`
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) (CLISSHConfigResponse, error) {
res, err := c.Request(ctx, http.MethodGet, "/api/v2/ssh-config", nil)
if err != nil {
return CLISSHConfigResponse{}, err
}
defer res.Body.Close()

if res.StatusCode != http.StatusOK {
return CLISSHConfigResponse{}, ReadBodyAsError(res)
}

var cliConfig CLISSHConfigResponse
return cliConfig, json.NewDecoder(res.Body).Decode(&cliConfig)
}
13 changes: 13 additions & 0 deletions site/src/api/typesGenerated.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,18 @@ export interface BuildInfoResponse {
readonly version: string
}

// From codersdk/deployment.go
export interface CLISSHConfig {
readonly DeploymentName: string
readonly SSHConfigOptions: string[]
}

// From codersdk/deployment.go
export interface CLISSHConfigResponse {
readonly deployment_name: string
readonly ssh_config_options: Record<string, string>
}

// From codersdk/parameters.go
export interface ComputedParameter extends Parameter {
readonly source_value: string
Expand Down Expand Up @@ -359,6 +371,7 @@ export interface DeploymentValues {
// Named type "github.com/coder/coder/cli/clibase.Struct[[]github.com/coder/coder/codersdk.GitAuthConfig]" unknown, using "any"
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- TODO explain why this is needed
readonly git_auth?: any
readonly cli_ssh?: CLISSHConfig
readonly config?: string
readonly write_config?: boolean
// Named type "github.com/coder/coder/cli/clibase.HostPort" unknown, using "any"
Expand Down