coder/scaletest/agentconn/config.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
}