mirror of https://github.com/coder/coder.git
90 lines
2.8 KiB
Go
90 lines
2.8 KiB
Go
package agentconn
|
|
|
|
import (
|
|
"net/url"
|
|
|
|
"github.com/google/uuid"
|
|
"golang.org/x/xerrors"
|
|
|
|
"github.com/coder/coder/v2/coderd/httpapi"
|
|
)
|
|
|
|
type ConnectionMode string
|
|
|
|
const (
|
|
ConnectionModeDirect ConnectionMode = "direct"
|
|
ConnectionModeDerp ConnectionMode = "derp"
|
|
)
|
|
|
|
type Config struct {
|
|
// AgentID is the ID of the agent to connect to.
|
|
AgentID uuid.UUID `json:"agent_id"`
|
|
// ConnectionMode is the strategy to use when connecting to the agent.
|
|
ConnectionMode ConnectionMode `json:"connection_mode"`
|
|
// HoldDuration is the duration to hold the connection open for. If set to
|
|
// 0, the connection will be closed immediately after making each request
|
|
// once.
|
|
HoldDuration httpapi.Duration `json:"hold_duration"`
|
|
|
|
// Connections is the list of connections to make to services running
|
|
// inside the workspace. Only HTTP connections are supported.
|
|
Connections []Connection `json:"connections"`
|
|
}
|
|
|
|
type Connection struct {
|
|
// URL is the address to connect to (e.g. "http://127.0.0.1:8080/path"). The
|
|
// endpoint must respond with a any response within timeout. The IP address
|
|
// is ignored and the connection is made to the agent's WireGuard IP
|
|
// instead.
|
|
URL string `json:"url"`
|
|
// Interval is the duration to wait between connections to this endpoint. If
|
|
// set to 0, the connection will only be made once. Must be set to 0 if
|
|
// the parent config's hold_duration is set to 0.
|
|
Interval httpapi.Duration `json:"interval"`
|
|
// Timeout is the duration to wait for a connection to this endpoint to
|
|
// succeed. If set to 0, the default timeout will be used.
|
|
Timeout httpapi.Duration `json:"timeout"`
|
|
}
|
|
|
|
func (c Config) Validate() error {
|
|
if c.AgentID == uuid.Nil {
|
|
return xerrors.New("agent_id must be set")
|
|
}
|
|
if c.ConnectionMode == "" {
|
|
return xerrors.New("connection_mode must be set")
|
|
}
|
|
switch c.ConnectionMode {
|
|
case ConnectionModeDirect:
|
|
case ConnectionModeDerp:
|
|
default:
|
|
return xerrors.Errorf("invalid connection_mode: %q", c.ConnectionMode)
|
|
}
|
|
if c.HoldDuration < 0 {
|
|
return xerrors.New("hold_duration must be a positive value")
|
|
}
|
|
|
|
for i, conn := range c.Connections {
|
|
if conn.URL == "" {
|
|
return xerrors.Errorf("connections[%d].url must be set", i)
|
|
}
|
|
u, err := url.Parse(conn.URL)
|
|
if err != nil {
|
|
return xerrors.Errorf("connections[%d].url is not a valid URL: %w", i, err)
|
|
}
|
|
if u.Scheme != "http" {
|
|
return xerrors.Errorf("connections[%d].url has an unsupported scheme %q, only http is supported", i, u.Scheme)
|
|
}
|
|
if conn.Interval < 0 {
|
|
return xerrors.Errorf("connections[%d].interval must be a positive value", i)
|
|
}
|
|
if conn.Interval > 0 && c.HoldDuration == 0 {
|
|
return xerrors.Errorf("connections[%d].interval must be 0 if hold_duration is 0", i)
|
|
}
|
|
if conn.Timeout < 0 {
|
|
return xerrors.Errorf("connections[%d].timeout must be a positive value", i)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|