Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
55 changes: 28 additions & 27 deletions go/cmd/api/config.go
Original file line number Diff line number Diff line change
@@ -1,46 +1,47 @@
package api

type nodeConfig struct {
Platform string `json:"platform,omitempty" description:"The platform this agent is running on"`
Image string `json:"image,omitempty" description:"The image this agent is running"`
HttpPort int `json:"httpPort" default:"7070" description:"Port to listen on"`
Schema string `json:"$schema,omitempty" description:"Make jsonschema happy"`
Region string `json:"region,omitempty" description:"The region this agent is running in"`
Platform string `json:"platform,omitempty" description:"Cloud platform identifier (e.g., aws, gcp, hetzner)"`
Image string `json:"image,omitempty" description:"Container image identifier including repository and tag"`
HttpPort int `json:"httpPort" default:"7070" description:"HTTP port for the API server to listen on"`
Schema string `json:"$schema,omitempty" description:"JSON Schema URI for configuration validation"`
Region string `json:"region,omitempty" description:"Geographic region identifier where this node is deployed"`
Heartbeat *struct {
URL string `json:"url" minLength:"1" description:"URL to send heartbeat to"`
Interval int `json:"interval" min:"1" description:"Interval in seconds to send heartbeat"`
} `json:"heartbeat,omitempty" description:"Send heartbeat to a URL"`
URL string `json:"url" minLength:"1" description:"Complete URL endpoint where heartbeat signals will be sent"`
Interval int `json:"interval" min:"1" description:"Time between heartbeat signals in seconds"`
} `json:"heartbeat,omitempty" description:"Configuration for health check heartbeat mechanism"`

Cluster *struct {
NodeID string `json:"nodeId,omitempty" description:"A unique node id"`
NodeID string `json:"nodeId,omitempty" description:"Unique identifier for this node within the cluster"`
AdvertiseAddr struct {
Static *string `json:"static,omitempty" description:"The address to advertise to other nodes"`
AwsEcsMetadata *bool `json:"awsEcsMetadata,omitempty" description:"Use AWS ECS metadata to retrieve the address of the current node"`
} `json:"advertiseAddr" description:"A mechanism of retrieving the address of the current node."`
RpcPort string `json:"rpcPort" default:"7071" description:"The port used for RPC"`
GossipPort string `json:"gossipPort" default:"7072" description:"The port used for gossip"`
Static *string `json:"static,omitempty" description:"Static IP address or hostname for node discovery"`
AwsEcsMetadata *bool `json:"awsEcsMetadata,omitempty" description:"Enable automatic address discovery using AWS ECS container metadata"`
} `json:"advertiseAddr" description:"Node address advertisement configuration for cluster communication"`
RpcPort string `json:"rpcPort" default:"7071" description:"Port used for internal RPC communication between nodes"`
GossipPort string `json:"gossipPort" default:"7072" description:"Port used for cluster membership and failure detection"`
Discovery *struct {
Static *struct {
Addrs []string `json:"addrs" minLength:"1" description:"List of node addresses"`
} `json:"static,omitempty" description:"Static cluster discovery configuration"`
Addrs []string `json:"addrs" minLength:"1" description:"List of seed node addresses for static cluster configuration"`
} `json:"static,omitempty" description:"Static cluster membership configuration"`
Redis *struct {
URL string `json:"url" minLength:"1" description:"Redis URL"`
} `json:"redis,omitempty" description:"Redis cluster discovery configuration"`
} `json:"discovery,omitempty" description:"Cluster discovery configuration, only one supported: static, cloudmap"`
} `json:"cluster,omitempty" description:"Cluster configuration"`
URL string `json:"url" minLength:"1" description:"Redis connection string for dynamic cluster discovery"`
} `json:"redis,omitempty" description:"Redis-based cluster discovery configuration"`
} `json:"discovery,omitempty" description:"Cluster node discovery mechanism configuration"`
} `json:"cluster,omitempty" description:"Distributed cluster configuration settings"`

Logs *struct {
Color bool `json:"color" description:"Display color in logs"`
Color bool `json:"color" description:"Enable ANSI color codes in log output"`
} `json:"logs,omitempty"`
Clickhouse *struct {
Url string `json:"url" minLength:"1"`
Url string `json:"url" minLength:"1" description:"ClickHouse database connection string"`
} `json:"clickhouse,omitempty"`

Database struct {
// DSN of the primary database for reads and writes.
Primary string `json:"primary"`

// An optional read replica DSN.
ReadonlyReplica string `json:"readonlyReplica,omitempty"`
Primary string `json:"primary" description:"Primary database connection string for read and write operations"`
ReadonlyReplica string `json:"readonlyReplica,omitempty" description:"Optional read-replica database connection string for read operations"`
} `json:"database"`

Otel *struct {
OtlpEndpoint string `json:"otlpEndpoint" description:"OpenTelemetry collector endpoint for metrics, traces, and logs"`
} `json:"otel,omitempty" description:"OpenTelemetry observability configuration"`
}
25 changes: 19 additions & 6 deletions go/cmd/api/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import (
"github.com/unkeyed/unkey/go/pkg/discovery"
"github.com/unkeyed/unkey/go/pkg/logging"
"github.com/unkeyed/unkey/go/pkg/membership"
"github.com/unkeyed/unkey/go/pkg/otel"
"github.com/unkeyed/unkey/go/pkg/shutdown"
"github.com/unkeyed/unkey/go/pkg/uid"
"github.com/unkeyed/unkey/go/pkg/version"
"github.com/unkeyed/unkey/go/pkg/zen"
Expand Down Expand Up @@ -54,7 +56,7 @@ var Cmd = &cli.Command{
// nolint:gocognit
func run(cliC *cli.Context) error {

shutdowns := []func(ctx context.Context) error{}
shutdowns := []shutdown.ShutdownFn{}

if cliC.Bool("generate-config-schema") {
// nolint:exhaustruct
Expand Down Expand Up @@ -111,6 +113,18 @@ func run(cliC *cli.Context) error {

logger.Info(ctx, "configration loaded", slog.String("file", configFile))

if cfg.Otel != nil {
shutdownOtel, grafanaErr := otel.InitGrafana(ctx, otel.Config{
GrafanaEndpoint: cfg.Otel.OtlpEndpoint,
Application: "api",
Version: version.Version,
})
if grafanaErr != nil {
return fmt.Errorf("unable to init grafana: %w", grafanaErr)
}
shutdowns = append(shutdowns, shutdownOtel...)
}

db, err := database.New(database.Config{
PrimaryDSN: cfg.Database.Primary,
ReadOnlyDSN: cfg.Database.ReadonlyReplica,
Expand Down Expand Up @@ -189,7 +203,7 @@ func run(cliC *cli.Context) error {
return gracefulShutdown(ctx, logger, shutdowns)
}

func gracefulShutdown(ctx context.Context, logger logging.Logger, shutdowns []func(ctx context.Context) error) error {
func gracefulShutdown(ctx context.Context, logger logging.Logger, shutdowns []shutdown.ShutdownFn) error {
cShutdown := make(chan os.Signal, 1)
signal.Notify(cShutdown, os.Interrupt, syscall.SIGTERM)

Expand All @@ -212,13 +226,12 @@ func gracefulShutdown(ctx context.Context, logger logging.Logger, shutdowns []fu
return nil
}

func setupCluster(cfg nodeConfig, logger logging.Logger) (cluster.Cluster, []func(ctx context.Context) error, error) {
func setupCluster(cfg nodeConfig, logger logging.Logger) (cluster.Cluster, []shutdown.ShutdownFn, error) {
shutdowns := []shutdown.ShutdownFn{}
if cfg.Cluster == nil {
return cluster.NewNoop("", "127.0.0.1"), []func(ctx context.Context) error{}, nil
return cluster.NewNoop("", "127.0.0.1"), shutdowns, nil
}

shutdowns := []func(ctx context.Context) error{}

var advertiseAddr string
{
switch {
Expand Down
1 change: 1 addition & 0 deletions go/cmd/healthcheck/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ func run(cliC *cli.Context) error {
return fmt.Errorf("You must provide a url like so: 'unkey healthcheck <url>'")
}

// nolint:gosec
res, err := http.Get(url)
if err != nil {
return fmt.Errorf("failed to perform healthcheck: %w", err)
Expand Down
23 changes: 9 additions & 14 deletions go/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,10 @@ require (
connectrpc.com/connect v1.16.2
connectrpc.com/otelconnect v0.7.1
github.com/ClickHouse/clickhouse-go/v2 v2.31.0
github.com/Southclaws/fault v0.8.1
github.com/axiomhq/axiom-go v0.22.0
github.com/btcsuite/btcutil v1.0.2
github.com/danielgtaylor/huma v1.14.3
github.com/go-sql-driver/mysql v1.8.1
github.com/gonum/stat v0.0.0-20181125101827-41a0da705a5b
github.com/google/uuid v1.6.0
github.com/hashicorp/memberlist v0.5.3
github.com/lmittmann/tint v1.0.7
github.com/maypok86/otter v1.2.4
Expand All @@ -28,7 +25,14 @@ require (
github.com/unkeyed/unkey/apps/agent v0.0.0-20250211105155-776bdbccce47
github.com/urfave/cli/v2 v2.27.5
github.com/xeipuuv/gojsonschema v1.2.0
go.opentelemetry.io/contrib/instrumentation/runtime v0.59.0
go.opentelemetry.io/otel v1.34.0
go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v1.29.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0
go.opentelemetry.io/otel/metric v1.34.0
go.opentelemetry.io/otel/sdk v1.34.0
go.opentelemetry.io/otel/sdk/metric v1.34.0
go.opentelemetry.io/otel/trace v1.34.0
google.golang.org/protobuf v1.36.5
)
Expand All @@ -44,6 +48,7 @@ require (
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/antlr4-go/antlr/v4 v4.13.1 // indirect
github.com/armon/go-metrics v0.4.1 // indirect
github.com/axiomhq/axiom-go v0.20.2 // indirect
github.com/bahlo/generic-list-go v0.2.0 // indirect
github.com/buger/jsonparser v1.1.1 // indirect
github.com/cenkalti/backoff/v4 v4.3.0 // indirect
Expand All @@ -63,7 +68,6 @@ require (
github.com/dprotaso/go-yit v0.0.0-20240618133044-5a0af90af097 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/fatih/structtag v1.2.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/gammazero/deque v1.0.0 // indirect
github.com/getkin/kin-openapi v0.127.0 // indirect
github.com/go-faster/city v1.0.1 // indirect
Expand All @@ -81,19 +85,17 @@ require (
github.com/gonum/matrix v0.0.0-20181209220409-c518dec07be9 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/cel-go v0.22.1 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/pprof v0.0.0-20241210010833-40e02aabc2ad // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.26.1 // indirect
github.com/hashicorp/errwrap v1.1.0 // indirect
github.com/hashicorp/go-immutable-radix v1.3.1 // indirect
github.com/hashicorp/go-metrics v0.5.4 // indirect
github.com/hashicorp/go-msgpack v0.5.5 // indirect
github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect
github.com/hashicorp/go-multierror v1.1.1 // indirect
github.com/hashicorp/go-sockaddr v1.0.7 // indirect
github.com/hashicorp/golang-lru v1.0.2 // indirect
github.com/hashicorp/serf v0.10.1 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/invopop/yaml v0.3.1 // indirect
github.com/jackc/pgpassfile v1.0.0 // indirect
Expand All @@ -104,7 +106,6 @@ require (
github.com/josharian/intern v1.0.0 // indirect
github.com/klauspost/compress v1.17.11 // indirect
github.com/mailru/easyjson v0.9.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/miekg/dns v1.1.63 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
Expand All @@ -128,7 +129,6 @@ require (
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect
github.com/riza-io/grpc-go v0.2.0 // indirect
github.com/rs/zerolog v1.33.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/santhosh-tekuri/jsonschema/v6 v6.0.1 // indirect
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 // indirect
Expand All @@ -150,11 +150,6 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.55.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.34.0 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.34.0 // indirect
go.opentelemetry.io/otel/metric v1.34.0 // indirect
go.opentelemetry.io/otel/sdk v1.34.0 // indirect
go.opentelemetry.io/proto/otlp v1.5.0 // indirect
go.uber.org/atomic v1.11.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
Expand Down
Loading
Loading