From 01dcd4011e576efcd7237f7b43a24c52e6fcccec Mon Sep 17 00:00:00 2001 From: Kristoffer Dalby Date: Wed, 17 Jun 2026 15:10:28 +0000 Subject: [PATCH] gen: generate v1 API server and client with ogen go generate (gen/api/v1) runs ogen against openapi/v1/headscale.yaml; ogen added as a tool dependency. CI freshness check covers openapi/. --- .github/workflows/check-generated.yml | 1 + flakehashes.json | 4 +- gen/api/v1/generate.go | 8 + gen/api/v1/oas_cfg_gen.go | 318 ++ gen/api/v1/oas_client_gen.go | 3981 ++++++++++++++++ gen/api/v1/oas_handlers_gen.go | 5836 +++++++++++++++++++++++ gen/api/v1/oas_json_gen.go | 4292 +++++++++++++++++ gen/api/v1/oas_labeler_gen.go | 42 + gen/api/v1/oas_middleware_gen.go | 10 + gen/api/v1/oas_operations_gen.go | 38 + gen/api/v1/oas_parameters_gen.go | 1335 ++++++ gen/api/v1/oas_request_decoders_gen.go | 938 ++++ gen/api/v1/oas_request_encoders_gen.go | 193 + gen/api/v1/oas_response_decoders_gen.go | 2502 ++++++++++ gen/api/v1/oas_response_encoders_gen.go | 415 ++ gen/api/v1/oas_router_gen.go | 1753 +++++++ gen/api/v1/oas_schemas_gen.go | 1732 +++++++ gen/api/v1/oas_security_gen.go | 119 + gen/api/v1/oas_server_gen.go | 210 + gen/api/v1/oas_unimplemented_gen.go | 283 ++ gen/api/v1/oas_validators_gen.go | 332 ++ go.mod | 18 +- go.sum | 28 + 23 files changed, 24384 insertions(+), 4 deletions(-) create mode 100644 gen/api/v1/generate.go create mode 100644 gen/api/v1/oas_cfg_gen.go create mode 100644 gen/api/v1/oas_client_gen.go create mode 100644 gen/api/v1/oas_handlers_gen.go create mode 100644 gen/api/v1/oas_json_gen.go create mode 100644 gen/api/v1/oas_labeler_gen.go create mode 100644 gen/api/v1/oas_middleware_gen.go create mode 100644 gen/api/v1/oas_operations_gen.go create mode 100644 gen/api/v1/oas_parameters_gen.go create mode 100644 gen/api/v1/oas_request_decoders_gen.go create mode 100644 gen/api/v1/oas_request_encoders_gen.go create mode 100644 gen/api/v1/oas_response_decoders_gen.go create mode 100644 gen/api/v1/oas_response_encoders_gen.go create mode 100644 gen/api/v1/oas_router_gen.go create mode 100644 gen/api/v1/oas_schemas_gen.go create mode 100644 gen/api/v1/oas_security_gen.go create mode 100644 gen/api/v1/oas_server_gen.go create mode 100644 gen/api/v1/oas_unimplemented_gen.go create mode 100644 gen/api/v1/oas_validators_gen.go diff --git a/.github/workflows/check-generated.yml b/.github/workflows/check-generated.yml index 71d721fa..3455660c 100644 --- a/.github/workflows/check-generated.yml +++ b/.github/workflows/check-generated.yml @@ -30,6 +30,7 @@ jobs: - '**/*.go' - '**/*.proto' - 'buf.gen.yaml' + - 'openapi/**' - 'tools/**' - uses: nixbuild/nix-quick-install-action@2c9db80fb984ceb1bcaa77cdda3fdf8cfba92035 # v34 if: steps.changed-files.outputs.files == 'true' diff --git a/flakehashes.json b/flakehashes.json index 37888e99..1b33efef 100644 --- a/flakehashes.json +++ b/flakehashes.json @@ -1,6 +1,6 @@ { "vendor": { - "goModSum": "sha256-csVm5v6HZ49PBp/FCX+yK1sjV8/nuUQz3GKN21Ne1mg=", - "sri": "sha256-fzKyXNMw/2yAEhaTZu0n1NXatPO2IP0HFA2ey1vZIYM=" + "goModSum": "sha256-xJ+t2r3IFtmRTZTMH35FDP70ZukO4IGuHNgOUigKVUI=", + "sri": "sha256-z4g85ET9IjHs5w3CDK7lxP4OheCwc8ozAtTfXwKEHaw=" } } diff --git a/gen/api/v1/generate.go b/gen/api/v1/generate.go new file mode 100644 index 00000000..ee370eb0 --- /dev/null +++ b/gen/api/v1/generate.go @@ -0,0 +1,8 @@ +// Package apiv1 contains the ogen-generated server and client for the +// Headscale v1 HTTP API. The code is generated from the committed OpenAPI 3.0 +// spec at openapi/v1/headscale.yaml — the single source of truth. Do not edit +// generated files by hand; run `make generate` (or `go generate ./...`) after +// changing the spec. +// +//go:generate go run github.com/ogen-go/ogen/cmd/ogen --target . --package apiv1 --clean ../../../openapi/v1/headscale.yaml +package apiv1 diff --git a/gen/api/v1/oas_cfg_gen.go b/gen/api/v1/oas_cfg_gen.go new file mode 100644 index 00000000..bc82d830 --- /dev/null +++ b/gen/api/v1/oas_cfg_gen.go @@ -0,0 +1,318 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "net/http" + "strings" + + ht "github.com/ogen-go/ogen/http" + "github.com/ogen-go/ogen/middleware" + "github.com/ogen-go/ogen/ogenerrors" + "github.com/ogen-go/ogen/otelogen" + "go.opentelemetry.io/otel" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/metric" + "go.opentelemetry.io/otel/trace" +) + +var ( + // Allocate option closure once. + clientSpanKind = trace.WithSpanKind(trace.SpanKindClient) + // Allocate option closure once. + serverSpanKind = trace.WithSpanKind(trace.SpanKindServer) +) + +type ( + optionFunc[C any] func(*C) + otelOptionFunc func(*otelConfig) +) + +type otelConfig struct { + TracerProvider trace.TracerProvider + Tracer trace.Tracer + MeterProvider metric.MeterProvider + Meter metric.Meter + Attributes []attribute.KeyValue +} + +func (cfg *otelConfig) initOTEL() { + if cfg.TracerProvider == nil { + cfg.TracerProvider = otel.GetTracerProvider() + } + if cfg.MeterProvider == nil { + cfg.MeterProvider = otel.GetMeterProvider() + } + cfg.Tracer = cfg.TracerProvider.Tracer(otelogen.Name, + trace.WithInstrumentationVersion(otelogen.SemVersion()), + ) + cfg.Meter = cfg.MeterProvider.Meter(otelogen.Name, + metric.WithInstrumentationVersion(otelogen.SemVersion()), + ) +} + +// ErrorHandler is error handler. +type ErrorHandler = ogenerrors.ErrorHandler + +type serverConfig struct { + otelConfig + NotFound http.HandlerFunc + MethodNotAllowed func(w http.ResponseWriter, r *http.Request, allowed string) + ErrorHandler ErrorHandler + Prefix string + Middleware Middleware + MaxMultipartMemory int64 +} + +// ServerOption is server config option. +type ServerOption interface { + applyServer(*serverConfig) +} + +var _ ServerOption = (optionFunc[serverConfig])(nil) + +func (o optionFunc[C]) applyServer(c *C) { + o(c) +} + +var _ ServerOption = (otelOptionFunc)(nil) + +func (o otelOptionFunc) applyServer(c *serverConfig) { + o(&c.otelConfig) +} + +func newServerConfig(opts ...ServerOption) serverConfig { + cfg := serverConfig{ + NotFound: http.NotFound, + MethodNotAllowed: nil, + ErrorHandler: ogenerrors.DefaultErrorHandler, + Middleware: nil, + MaxMultipartMemory: 32 << 20, // 32 MB + } + for _, opt := range opts { + opt.applyServer(&cfg) + } + cfg.initOTEL() + return cfg +} + +type baseServer struct { + cfg serverConfig + requests metric.Int64Counter + errors metric.Int64Counter + duration metric.Float64Histogram +} + +func (s baseServer) notFound(w http.ResponseWriter, r *http.Request) { + s.cfg.NotFound(w, r) +} + +type notAllowedParams struct { + allowedMethods string + allowedHeaders map[string]string + acceptPost string + acceptPatch string +} + +func (s baseServer) notAllowed(w http.ResponseWriter, r *http.Request, params notAllowedParams) { + h := w.Header() + isOptions := r.Method == "OPTIONS" + if isOptions { + h.Set("Access-Control-Allow-Methods", params.allowedMethods) + if params.allowedHeaders != nil { + m := r.Header.Get("Access-Control-Request-Method") + if m != "" { + allowedHeaders, ok := params.allowedHeaders[strings.ToUpper(m)] + if ok { + h.Set("Access-Control-Allow-Headers", allowedHeaders) + } + } + } + if params.acceptPost != "" { + h.Set("Accept-Post", params.acceptPost) + } + if params.acceptPatch != "" { + h.Set("Accept-Patch", params.acceptPatch) + } + } + if s.cfg.MethodNotAllowed != nil { + s.cfg.MethodNotAllowed(w, r, params.allowedMethods) + return + } + status := http.StatusNoContent + if !isOptions { + h.Set("Allow", params.allowedMethods) + status = http.StatusMethodNotAllowed + } + w.WriteHeader(status) +} + +func (cfg serverConfig) baseServer() (s baseServer, err error) { + s = baseServer{cfg: cfg} + if s.requests, err = otelogen.ServerRequestCountCounter(s.cfg.Meter); err != nil { + return s, err + } + if s.errors, err = otelogen.ServerErrorsCountCounter(s.cfg.Meter); err != nil { + return s, err + } + if s.duration, err = otelogen.ServerDurationHistogram(s.cfg.Meter); err != nil { + return s, err + } + return s, nil +} + +type clientConfig struct { + otelConfig + Client ht.Client +} + +// ClientOption is client config option. +type ClientOption interface { + applyClient(*clientConfig) +} + +var _ ClientOption = (optionFunc[clientConfig])(nil) + +func (o optionFunc[C]) applyClient(c *C) { + o(c) +} + +var _ ClientOption = (otelOptionFunc)(nil) + +func (o otelOptionFunc) applyClient(c *clientConfig) { + o(&c.otelConfig) +} + +func newClientConfig(opts ...ClientOption) clientConfig { + cfg := clientConfig{ + Client: http.DefaultClient, + } + for _, opt := range opts { + opt.applyClient(&cfg) + } + cfg.initOTEL() + return cfg +} + +type baseClient struct { + cfg clientConfig + requests metric.Int64Counter + errors metric.Int64Counter + duration metric.Float64Histogram +} + +func (cfg clientConfig) baseClient() (c baseClient, err error) { + c = baseClient{cfg: cfg} + if c.requests, err = otelogen.ClientRequestCountCounter(c.cfg.Meter); err != nil { + return c, err + } + if c.errors, err = otelogen.ClientErrorsCountCounter(c.cfg.Meter); err != nil { + return c, err + } + if c.duration, err = otelogen.ClientDurationHistogram(c.cfg.Meter); err != nil { + return c, err + } + return c, nil +} + +// Option is config option. +type Option interface { + ServerOption + ClientOption +} + +// WithTracerProvider specifies a tracer provider to use for creating a tracer. +// +// If none is specified, the global provider is used. +func WithTracerProvider(provider trace.TracerProvider) Option { + return otelOptionFunc(func(cfg *otelConfig) { + if provider != nil { + cfg.TracerProvider = provider + } + }) +} + +// WithMeterProvider specifies a meter provider to use for creating a meter. +// +// If none is specified, the otel.GetMeterProvider() is used. +func WithMeterProvider(provider metric.MeterProvider) Option { + return otelOptionFunc(func(cfg *otelConfig) { + if provider != nil { + cfg.MeterProvider = provider + } + }) +} + +// WithAttributes specifies default otel attributes. +func WithAttributes(attributes ...attribute.KeyValue) Option { + return otelOptionFunc(func(cfg *otelConfig) { + cfg.Attributes = attributes + }) +} + +// WithClient specifies http client to use. +func WithClient(client ht.Client) ClientOption { + return optionFunc[clientConfig](func(cfg *clientConfig) { + if client != nil { + cfg.Client = client + } + }) +} + +// WithNotFound specifies Not Found handler to use. +func WithNotFound(notFound http.HandlerFunc) ServerOption { + return optionFunc[serverConfig](func(cfg *serverConfig) { + if notFound != nil { + cfg.NotFound = notFound + } + }) +} + +// WithMethodNotAllowed specifies Method Not Allowed handler to use. +func WithMethodNotAllowed(methodNotAllowed func(w http.ResponseWriter, r *http.Request, allowed string)) ServerOption { + return optionFunc[serverConfig](func(cfg *serverConfig) { + if methodNotAllowed != nil { + cfg.MethodNotAllowed = methodNotAllowed + } + }) +} + +// WithErrorHandler specifies error handler to use. +func WithErrorHandler(h ErrorHandler) ServerOption { + return optionFunc[serverConfig](func(cfg *serverConfig) { + if h != nil { + cfg.ErrorHandler = h + } + }) +} + +// WithPathPrefix specifies server path prefix. +func WithPathPrefix(prefix string) ServerOption { + return optionFunc[serverConfig](func(cfg *serverConfig) { + cfg.Prefix = prefix + }) +} + +// WithMiddleware specifies middlewares to use. +func WithMiddleware(m ...Middleware) ServerOption { + return optionFunc[serverConfig](func(cfg *serverConfig) { + switch len(m) { + case 0: + cfg.Middleware = nil + case 1: + cfg.Middleware = m[0] + default: + cfg.Middleware = middleware.ChainMiddlewares(m...) + } + }) +} + +// WithMaxMultipartMemory specifies limit of memory for storing file parts. +// File parts which can't be stored in memory will be stored on disk in temporary files. +func WithMaxMultipartMemory(max int64) ServerOption { + return optionFunc[serverConfig](func(cfg *serverConfig) { + if max > 0 { + cfg.MaxMultipartMemory = max + } + }) +} diff --git a/gen/api/v1/oas_client_gen.go b/gen/api/v1/oas_client_gen.go new file mode 100644 index 00000000..3fa80b90 --- /dev/null +++ b/gen/api/v1/oas_client_gen.go @@ -0,0 +1,3981 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "context" + "io" + "net/url" + "strings" + "time" + + "github.com/go-faster/errors" + "github.com/ogen-go/ogen/conv" + ht "github.com/ogen-go/ogen/http" + "github.com/ogen-go/ogen/ogenerrors" + "github.com/ogen-go/ogen/otelogen" + "github.com/ogen-go/ogen/uri" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + semconv "go.opentelemetry.io/otel/semconv/v1.39.0" + "go.opentelemetry.io/otel/trace" +) + +func trimTrailingSlashes(u *url.URL) { + u.Path = strings.TrimRight(u.Path, "/") + u.RawPath = strings.TrimRight(u.RawPath, "/") +} + +// Invoker invokes operations described by OpenAPI v3 specification. +type Invoker interface { + // AuthApprove invokes AuthApprove operation. + // + // Approve a pending auth session. + // + // POST /api/v1/auth/approve + AuthApprove(ctx context.Context, request *AuthApproveReq) error + // AuthRegister invokes AuthRegister operation. + // + // Register a node via an auth id (alias of RegisterNode). + // + // POST /api/v1/auth/register + AuthRegister(ctx context.Context, request *AuthRegisterReq) (*AuthRegisterOK, error) + // AuthReject invokes AuthReject operation. + // + // Reject a pending auth session. + // + // POST /api/v1/auth/reject + AuthReject(ctx context.Context, request *AuthRejectReq) error + // BackfillNodeIPs invokes BackfillNodeIPs operation. + // + // Backfill missing IP addresses for all nodes. + // + // POST /api/v1/node/backfillips + BackfillNodeIPs(ctx context.Context, params BackfillNodeIPsParams) (*BackfillNodeIPsOK, error) + // CheckPolicy invokes CheckPolicy operation. + // + // Validate a policy against live users and nodes without storing it. + // + // POST /api/v1/policy/check + CheckPolicy(ctx context.Context, request *CheckPolicyReq) error + // CreateApiKey invokes CreateApiKey operation. + // + // Create an API key. + // + // POST /api/v1/apikey + CreateApiKey(ctx context.Context, request *CreateApiKeyReq) (*CreateApiKeyOK, error) + // CreatePreAuthKey invokes CreatePreAuthKey operation. + // + // Create a pre-auth key. + // + // POST /api/v1/preauthkey + CreatePreAuthKey(ctx context.Context, request *CreatePreAuthKeyReq) (*CreatePreAuthKeyOK, error) + // CreateUser invokes CreateUser operation. + // + // Create a user. + // + // POST /api/v1/user + CreateUser(ctx context.Context, request *CreateUserReq) (*CreateUserOK, error) + // DebugCreateNode invokes DebugCreateNode operation. + // + // Create a debug node and cache its registration (testing only). + // + // POST /api/v1/debug/node + DebugCreateNode(ctx context.Context, request *DebugCreateNodeReq) (*DebugCreateNodeOK, error) + // DeleteApiKey invokes DeleteApiKey operation. + // + // Delete an API key by prefix (or id). + // + // DELETE /api/v1/apikey/{prefix} + DeleteApiKey(ctx context.Context, params DeleteApiKeyParams) error + // DeleteNode invokes DeleteNode operation. + // + // Delete a node. + // + // DELETE /api/v1/node/{node_id} + DeleteNode(ctx context.Context, params DeleteNodeParams) error + // DeletePreAuthKey invokes DeletePreAuthKey operation. + // + // Delete a pre-auth key. + // + // DELETE /api/v1/preauthkey + DeletePreAuthKey(ctx context.Context, params DeletePreAuthKeyParams) error + // DeleteUser invokes DeleteUser operation. + // + // Delete a user. + // + // DELETE /api/v1/user/{id} + DeleteUser(ctx context.Context, params DeleteUserParams) error + // ExpireApiKey invokes ExpireApiKey operation. + // + // Expire an API key by id or prefix. + // + // POST /api/v1/apikey/expire + ExpireApiKey(ctx context.Context, request *ExpireApiKeyReq) error + // ExpireNode invokes ExpireNode operation. + // + // Expire a node, or disable its expiry. + // + // POST /api/v1/node/{node_id}/expire + ExpireNode(ctx context.Context, params ExpireNodeParams) (*ExpireNodeOK, error) + // ExpirePreAuthKey invokes ExpirePreAuthKey operation. + // + // Expire a pre-auth key. + // + // POST /api/v1/preauthkey/expire + ExpirePreAuthKey(ctx context.Context, request *ExpirePreAuthKeyReq) error + // GetNode invokes GetNode operation. + // + // Get a node by id. + // + // GET /api/v1/node/{node_id} + GetNode(ctx context.Context, params GetNodeParams) (*GetNodeOK, error) + // GetPolicy invokes GetPolicy operation. + // + // Get the current ACL policy. + // + // GET /api/v1/policy + GetPolicy(ctx context.Context) (*GetPolicyOK, error) + // Health invokes Health operation. + // + // Report server health, including database connectivity. + // + // GET /api/v1/health + Health(ctx context.Context) (*HealthOK, error) + // ListApiKeys invokes ListApiKeys operation. + // + // List all API keys. + // + // GET /api/v1/apikey + ListApiKeys(ctx context.Context) (*ListApiKeysOK, error) + // ListNodes invokes ListNodes operation. + // + // List nodes, optionally filtered by user. + // + // GET /api/v1/node + ListNodes(ctx context.Context, params ListNodesParams) (*ListNodesOK, error) + // ListPreAuthKeys invokes ListPreAuthKeys operation. + // + // List all pre-auth keys. + // + // GET /api/v1/preauthkey + ListPreAuthKeys(ctx context.Context) (*ListPreAuthKeysOK, error) + // ListUsers invokes ListUsers operation. + // + // List users, optionally filtered by id, name, or email. + // + // GET /api/v1/user + ListUsers(ctx context.Context, params ListUsersParams) (*ListUsersOK, error) + // RegisterNode invokes RegisterNode operation. + // + // Register a node to a user using a registration id. + // + // POST /api/v1/node/register + RegisterNode(ctx context.Context, params RegisterNodeParams) (*RegisterNodeOK, error) + // RenameNode invokes RenameNode operation. + // + // Rename a node. + // + // POST /api/v1/node/{node_id}/rename/{new_name} + RenameNode(ctx context.Context, params RenameNodeParams) (*RenameNodeOK, error) + // RenameUser invokes RenameUser operation. + // + // Rename a user. + // + // POST /api/v1/user/{old_id}/rename/{new_name} + RenameUser(ctx context.Context, params RenameUserParams) (*RenameUserOK, error) + // SetApprovedRoutes invokes SetApprovedRoutes operation. + // + // Set the approved subnet routes of a node. + // + // POST /api/v1/node/{node_id}/approve_routes + SetApprovedRoutes(ctx context.Context, request *SetApprovedRoutesReq, params SetApprovedRoutesParams) (*SetApprovedRoutesOK, error) + // SetPolicy invokes SetPolicy operation. + // + // Set the ACL policy (database policy mode only). + // + // PUT /api/v1/policy + SetPolicy(ctx context.Context, request *SetPolicyReq) (*SetPolicyOK, error) + // SetTags invokes SetTags operation. + // + // Set the tags of a node (converts it to a tagged node). + // + // POST /api/v1/node/{node_id}/tags + SetTags(ctx context.Context, request *SetTagsReq, params SetTagsParams) (*SetTagsOK, error) +} + +// Client implements OAS client. +type Client struct { + serverURL *url.URL + sec SecuritySource + baseClient +} + +// NewClient initializes new Client defined by OAS. +func NewClient(serverURL string, sec SecuritySource, opts ...ClientOption) (*Client, error) { + u, err := url.Parse(serverURL) + if err != nil { + return nil, err + } + trimTrailingSlashes(u) + + c, err := newClientConfig(opts...).baseClient() + if err != nil { + return nil, err + } + return &Client{ + serverURL: u, + sec: sec, + baseClient: c, + }, nil +} + +type serverURLKey struct{} + +// WithServerURL sets context key to override server URL. +func WithServerURL(ctx context.Context, u *url.URL) context.Context { + return context.WithValue(ctx, serverURLKey{}, u) +} + +func (c *Client) requestURL(ctx context.Context) *url.URL { + u, ok := ctx.Value(serverURLKey{}).(*url.URL) + if !ok { + return c.serverURL + } + return u +} + +// AuthApprove invokes AuthApprove operation. +// +// Approve a pending auth session. +// +// POST /api/v1/auth/approve +func (c *Client) AuthApprove(ctx context.Context, request *AuthApproveReq) error { + _, err := c.sendAuthApprove(ctx, request) + return err +} + +func (c *Client) sendAuthApprove(ctx context.Context, request *AuthApproveReq) (res *AuthApproveOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("AuthApprove"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/auth/approve"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, AuthApproveOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/auth/approve" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeAuthApproveRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, AuthApproveOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeAuthApproveResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// AuthRegister invokes AuthRegister operation. +// +// Register a node via an auth id (alias of RegisterNode). +// +// POST /api/v1/auth/register +func (c *Client) AuthRegister(ctx context.Context, request *AuthRegisterReq) (*AuthRegisterOK, error) { + res, err := c.sendAuthRegister(ctx, request) + return res, err +} + +func (c *Client) sendAuthRegister(ctx context.Context, request *AuthRegisterReq) (res *AuthRegisterOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("AuthRegister"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/auth/register"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, AuthRegisterOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/auth/register" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeAuthRegisterRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, AuthRegisterOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeAuthRegisterResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// AuthReject invokes AuthReject operation. +// +// Reject a pending auth session. +// +// POST /api/v1/auth/reject +func (c *Client) AuthReject(ctx context.Context, request *AuthRejectReq) error { + _, err := c.sendAuthReject(ctx, request) + return err +} + +func (c *Client) sendAuthReject(ctx context.Context, request *AuthRejectReq) (res *AuthRejectOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("AuthReject"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/auth/reject"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, AuthRejectOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/auth/reject" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeAuthRejectRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, AuthRejectOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeAuthRejectResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// BackfillNodeIPs invokes BackfillNodeIPs operation. +// +// Backfill missing IP addresses for all nodes. +// +// POST /api/v1/node/backfillips +func (c *Client) BackfillNodeIPs(ctx context.Context, params BackfillNodeIPsParams) (*BackfillNodeIPsOK, error) { + res, err := c.sendBackfillNodeIPs(ctx, params) + return res, err +} + +func (c *Client) sendBackfillNodeIPs(ctx context.Context, params BackfillNodeIPsParams) (res *BackfillNodeIPsOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("BackfillNodeIPs"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/node/backfillips"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, BackfillNodeIPsOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/node/backfillips" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeQueryParams" + q := uri.NewQueryEncoder() + { + // Encode "confirmed" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "confirmed", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.Confirmed.Get(); ok { + return e.EncodeValue(conv.BoolToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, BackfillNodeIPsOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeBackfillNodeIPsResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// CheckPolicy invokes CheckPolicy operation. +// +// Validate a policy against live users and nodes without storing it. +// +// POST /api/v1/policy/check +func (c *Client) CheckPolicy(ctx context.Context, request *CheckPolicyReq) error { + _, err := c.sendCheckPolicy(ctx, request) + return err +} + +func (c *Client) sendCheckPolicy(ctx context.Context, request *CheckPolicyReq) (res *CheckPolicyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CheckPolicy"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/policy/check"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, CheckPolicyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/policy/check" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCheckPolicyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, CheckPolicyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeCheckPolicyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// CreateApiKey invokes CreateApiKey operation. +// +// Create an API key. +// +// POST /api/v1/apikey +func (c *Client) CreateApiKey(ctx context.Context, request *CreateApiKeyReq) (*CreateApiKeyOK, error) { + res, err := c.sendCreateApiKey(ctx, request) + return res, err +} + +func (c *Client) sendCreateApiKey(ctx context.Context, request *CreateApiKeyReq) (res *CreateApiKeyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CreateApiKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/apikey"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, CreateApiKeyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/apikey" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCreateApiKeyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, CreateApiKeyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeCreateApiKeyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// CreatePreAuthKey invokes CreatePreAuthKey operation. +// +// Create a pre-auth key. +// +// POST /api/v1/preauthkey +func (c *Client) CreatePreAuthKey(ctx context.Context, request *CreatePreAuthKeyReq) (*CreatePreAuthKeyOK, error) { + res, err := c.sendCreatePreAuthKey(ctx, request) + return res, err +} + +func (c *Client) sendCreatePreAuthKey(ctx context.Context, request *CreatePreAuthKeyReq) (res *CreatePreAuthKeyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CreatePreAuthKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/preauthkey"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, CreatePreAuthKeyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/preauthkey" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCreatePreAuthKeyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, CreatePreAuthKeyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeCreatePreAuthKeyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// CreateUser invokes CreateUser operation. +// +// Create a user. +// +// POST /api/v1/user +func (c *Client) CreateUser(ctx context.Context, request *CreateUserReq) (*CreateUserOK, error) { + res, err := c.sendCreateUser(ctx, request) + return res, err +} + +func (c *Client) sendCreateUser(ctx context.Context, request *CreateUserReq) (res *CreateUserOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CreateUser"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/user"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, CreateUserOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/user" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeCreateUserRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, CreateUserOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeCreateUserResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// DebugCreateNode invokes DebugCreateNode operation. +// +// Create a debug node and cache its registration (testing only). +// +// POST /api/v1/debug/node +func (c *Client) DebugCreateNode(ctx context.Context, request *DebugCreateNodeReq) (*DebugCreateNodeOK, error) { + res, err := c.sendDebugCreateNode(ctx, request) + return res, err +} + +func (c *Client) sendDebugCreateNode(ctx context.Context, request *DebugCreateNodeReq) (res *DebugCreateNodeOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DebugCreateNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/debug/node"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, DebugCreateNodeOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/debug/node" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeDebugCreateNodeRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, DebugCreateNodeOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeDebugCreateNodeResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// DeleteApiKey invokes DeleteApiKey operation. +// +// Delete an API key by prefix (or id). +// +// DELETE /api/v1/apikey/{prefix} +func (c *Client) DeleteApiKey(ctx context.Context, params DeleteApiKeyParams) error { + _, err := c.sendDeleteApiKey(ctx, params) + return err +} + +func (c *Client) sendDeleteApiKey(ctx context.Context, params DeleteApiKeyParams) (res *DeleteApiKeyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeleteApiKey"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.URLTemplateKey.String("/api/v1/apikey/{prefix}"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, DeleteApiKeyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/api/v1/apikey/" + { + // Encode "prefix" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "prefix", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.StringToString(params.Prefix)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeQueryParams" + q := uri.NewQueryEncoder() + { + // Encode "id" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "id", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.ID.Get(); ok { + return e.EncodeValue(conv.Uint64ToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "DELETE", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, DeleteApiKeyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeDeleteApiKeyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// DeleteNode invokes DeleteNode operation. +// +// Delete a node. +// +// DELETE /api/v1/node/{node_id} +func (c *Client) DeleteNode(ctx context.Context, params DeleteNodeParams) error { + _, err := c.sendDeleteNode(ctx, params) + return err +} + +func (c *Client) sendDeleteNode(ctx context.Context, params DeleteNodeParams) (res *DeleteNodeOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeleteNode"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.URLTemplateKey.String("/api/v1/node/{node_id}"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, DeleteNodeOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/api/v1/node/" + { + // Encode "node_id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "node_id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.NodeID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "DELETE", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, DeleteNodeOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeDeleteNodeResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// DeletePreAuthKey invokes DeletePreAuthKey operation. +// +// Delete a pre-auth key. +// +// DELETE /api/v1/preauthkey +func (c *Client) DeletePreAuthKey(ctx context.Context, params DeletePreAuthKeyParams) error { + _, err := c.sendDeletePreAuthKey(ctx, params) + return err +} + +func (c *Client) sendDeletePreAuthKey(ctx context.Context, params DeletePreAuthKeyParams) (res *DeletePreAuthKeyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeletePreAuthKey"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.URLTemplateKey.String("/api/v1/preauthkey"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, DeletePreAuthKeyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/preauthkey" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeQueryParams" + q := uri.NewQueryEncoder() + { + // Encode "id" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "id", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.ID.Get(); ok { + return e.EncodeValue(conv.Uint64ToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "DELETE", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, DeletePreAuthKeyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeDeletePreAuthKeyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// DeleteUser invokes DeleteUser operation. +// +// Delete a user. +// +// DELETE /api/v1/user/{id} +func (c *Client) DeleteUser(ctx context.Context, params DeleteUserParams) error { + _, err := c.sendDeleteUser(ctx, params) + return err +} + +func (c *Client) sendDeleteUser(ctx context.Context, params DeleteUserParams) (res *DeleteUserOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeleteUser"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.URLTemplateKey.String("/api/v1/user/{id}"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, DeleteUserOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/api/v1/user/" + { + // Encode "id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.ID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "DELETE", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, DeleteUserOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeDeleteUserResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// ExpireApiKey invokes ExpireApiKey operation. +// +// Expire an API key by id or prefix. +// +// POST /api/v1/apikey/expire +func (c *Client) ExpireApiKey(ctx context.Context, request *ExpireApiKeyReq) error { + _, err := c.sendExpireApiKey(ctx, request) + return err +} + +func (c *Client) sendExpireApiKey(ctx context.Context, request *ExpireApiKeyReq) (res *ExpireApiKeyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ExpireApiKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/apikey/expire"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, ExpireApiKeyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/apikey/expire" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeExpireApiKeyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, ExpireApiKeyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeExpireApiKeyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// ExpireNode invokes ExpireNode operation. +// +// Expire a node, or disable its expiry. +// +// POST /api/v1/node/{node_id}/expire +func (c *Client) ExpireNode(ctx context.Context, params ExpireNodeParams) (*ExpireNodeOK, error) { + res, err := c.sendExpireNode(ctx, params) + return res, err +} + +func (c *Client) sendExpireNode(ctx context.Context, params ExpireNodeParams) (res *ExpireNodeOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ExpireNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/node/{node_id}/expire"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, ExpireNodeOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [3]string + pathParts[0] = "/api/v1/node/" + { + // Encode "node_id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "node_id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.NodeID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + pathParts[2] = "/expire" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeQueryParams" + q := uri.NewQueryEncoder() + { + // Encode "expiry" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "expiry", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.Expiry.Get(); ok { + return e.EncodeValue(conv.DateTimeToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + { + // Encode "disable_expiry" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "disable_expiry", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.DisableExpiry.Get(); ok { + return e.EncodeValue(conv.BoolToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, ExpireNodeOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeExpireNodeResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// ExpirePreAuthKey invokes ExpirePreAuthKey operation. +// +// Expire a pre-auth key. +// +// POST /api/v1/preauthkey/expire +func (c *Client) ExpirePreAuthKey(ctx context.Context, request *ExpirePreAuthKeyReq) error { + _, err := c.sendExpirePreAuthKey(ctx, request) + return err +} + +func (c *Client) sendExpirePreAuthKey(ctx context.Context, request *ExpirePreAuthKeyReq) (res *ExpirePreAuthKeyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ExpirePreAuthKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/preauthkey/expire"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, ExpirePreAuthKeyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/preauthkey/expire" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeExpirePreAuthKeyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, ExpirePreAuthKeyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeExpirePreAuthKeyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// GetNode invokes GetNode operation. +// +// Get a node by id. +// +// GET /api/v1/node/{node_id} +func (c *Client) GetNode(ctx context.Context, params GetNodeParams) (*GetNodeOK, error) { + res, err := c.sendGetNode(ctx, params) + return res, err +} + +func (c *Client) sendGetNode(ctx context.Context, params GetNodeParams) (res *GetNodeOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("GetNode"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.URLTemplateKey.String("/api/v1/node/{node_id}"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, GetNodeOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [2]string + pathParts[0] = "/api/v1/node/" + { + // Encode "node_id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "node_id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.NodeID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, GetNodeOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeGetNodeResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// GetPolicy invokes GetPolicy operation. +// +// Get the current ACL policy. +// +// GET /api/v1/policy +func (c *Client) GetPolicy(ctx context.Context) (*GetPolicyOK, error) { + res, err := c.sendGetPolicy(ctx) + return res, err +} + +func (c *Client) sendGetPolicy(ctx context.Context) (res *GetPolicyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("GetPolicy"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.URLTemplateKey.String("/api/v1/policy"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, GetPolicyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/policy" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, GetPolicyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeGetPolicyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// Health invokes Health operation. +// +// Report server health, including database connectivity. +// +// GET /api/v1/health +func (c *Client) Health(ctx context.Context) (*HealthOK, error) { + res, err := c.sendHealth(ctx) + return res, err +} + +func (c *Client) sendHealth(ctx context.Context) (res *HealthOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("Health"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.URLTemplateKey.String("/api/v1/health"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, HealthOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/health" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, HealthOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeHealthResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// ListApiKeys invokes ListApiKeys operation. +// +// List all API keys. +// +// GET /api/v1/apikey +func (c *Client) ListApiKeys(ctx context.Context) (*ListApiKeysOK, error) { + res, err := c.sendListApiKeys(ctx) + return res, err +} + +func (c *Client) sendListApiKeys(ctx context.Context) (res *ListApiKeysOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListApiKeys"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.URLTemplateKey.String("/api/v1/apikey"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, ListApiKeysOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/apikey" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, ListApiKeysOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeListApiKeysResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// ListNodes invokes ListNodes operation. +// +// List nodes, optionally filtered by user. +// +// GET /api/v1/node +func (c *Client) ListNodes(ctx context.Context, params ListNodesParams) (*ListNodesOK, error) { + res, err := c.sendListNodes(ctx, params) + return res, err +} + +func (c *Client) sendListNodes(ctx context.Context, params ListNodesParams) (res *ListNodesOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListNodes"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.URLTemplateKey.String("/api/v1/node"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, ListNodesOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/node" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeQueryParams" + q := uri.NewQueryEncoder() + { + // Encode "user" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "user", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.User.Get(); ok { + return e.EncodeValue(conv.StringToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, ListNodesOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeListNodesResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// ListPreAuthKeys invokes ListPreAuthKeys operation. +// +// List all pre-auth keys. +// +// GET /api/v1/preauthkey +func (c *Client) ListPreAuthKeys(ctx context.Context) (*ListPreAuthKeysOK, error) { + res, err := c.sendListPreAuthKeys(ctx) + return res, err +} + +func (c *Client) sendListPreAuthKeys(ctx context.Context) (res *ListPreAuthKeysOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListPreAuthKeys"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.URLTemplateKey.String("/api/v1/preauthkey"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, ListPreAuthKeysOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/preauthkey" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, ListPreAuthKeysOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeListPreAuthKeysResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// ListUsers invokes ListUsers operation. +// +// List users, optionally filtered by id, name, or email. +// +// GET /api/v1/user +func (c *Client) ListUsers(ctx context.Context, params ListUsersParams) (*ListUsersOK, error) { + res, err := c.sendListUsers(ctx, params) + return res, err +} + +func (c *Client) sendListUsers(ctx context.Context, params ListUsersParams) (res *ListUsersOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListUsers"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.URLTemplateKey.String("/api/v1/user"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, ListUsersOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/user" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeQueryParams" + q := uri.NewQueryEncoder() + { + // Encode "id" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "id", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.ID.Get(); ok { + return e.EncodeValue(conv.Uint64ToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + { + // Encode "name" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "name", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.Name.Get(); ok { + return e.EncodeValue(conv.StringToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + { + // Encode "email" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "email", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.Email.Get(); ok { + return e.EncodeValue(conv.StringToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "GET", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, ListUsersOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeListUsersResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// RegisterNode invokes RegisterNode operation. +// +// Register a node to a user using a registration id. +// +// POST /api/v1/node/register +func (c *Client) RegisterNode(ctx context.Context, params RegisterNodeParams) (*RegisterNodeOK, error) { + res, err := c.sendRegisterNode(ctx, params) + return res, err +} + +func (c *Client) sendRegisterNode(ctx context.Context, params RegisterNodeParams) (res *RegisterNodeOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("RegisterNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/node/register"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, RegisterNodeOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/node/register" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeQueryParams" + q := uri.NewQueryEncoder() + { + // Encode "user" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "user", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.User.Get(); ok { + return e.EncodeValue(conv.StringToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + { + // Encode "key" parameter. + cfg := uri.QueryParameterEncodingConfig{ + Name: "key", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.EncodeParam(cfg, func(e uri.Encoder) error { + if val, ok := params.Key.Get(); ok { + return e.EncodeValue(conv.StringToString(val)) + } + return nil + }); err != nil { + return res, errors.Wrap(err, "encode query") + } + } + u.RawQuery = q.Values().Encode() + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, RegisterNodeOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeRegisterNodeResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// RenameNode invokes RenameNode operation. +// +// Rename a node. +// +// POST /api/v1/node/{node_id}/rename/{new_name} +func (c *Client) RenameNode(ctx context.Context, params RenameNodeParams) (*RenameNodeOK, error) { + res, err := c.sendRenameNode(ctx, params) + return res, err +} + +func (c *Client) sendRenameNode(ctx context.Context, params RenameNodeParams) (res *RenameNodeOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("RenameNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/node/{node_id}/rename/{new_name}"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, RenameNodeOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [4]string + pathParts[0] = "/api/v1/node/" + { + // Encode "node_id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "node_id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.NodeID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + pathParts[2] = "/rename/" + { + // Encode "new_name" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "new_name", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.StringToString(params.NewName)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[3] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, RenameNodeOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeRenameNodeResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// RenameUser invokes RenameUser operation. +// +// Rename a user. +// +// POST /api/v1/user/{old_id}/rename/{new_name} +func (c *Client) RenameUser(ctx context.Context, params RenameUserParams) (*RenameUserOK, error) { + res, err := c.sendRenameUser(ctx, params) + return res, err +} + +func (c *Client) sendRenameUser(ctx context.Context, params RenameUserParams) (res *RenameUserOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("RenameUser"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/user/{old_id}/rename/{new_name}"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, RenameUserOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [4]string + pathParts[0] = "/api/v1/user/" + { + // Encode "old_id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "old_id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.OldID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + pathParts[2] = "/rename/" + { + // Encode "new_name" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "new_name", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.StringToString(params.NewName)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[3] = encoded + } + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, RenameUserOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeRenameUserResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// SetApprovedRoutes invokes SetApprovedRoutes operation. +// +// Set the approved subnet routes of a node. +// +// POST /api/v1/node/{node_id}/approve_routes +func (c *Client) SetApprovedRoutes(ctx context.Context, request *SetApprovedRoutesReq, params SetApprovedRoutesParams) (*SetApprovedRoutesOK, error) { + res, err := c.sendSetApprovedRoutes(ctx, request, params) + return res, err +} + +func (c *Client) sendSetApprovedRoutes(ctx context.Context, request *SetApprovedRoutesReq, params SetApprovedRoutesParams) (res *SetApprovedRoutesOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("SetApprovedRoutes"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/node/{node_id}/approve_routes"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, SetApprovedRoutesOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [3]string + pathParts[0] = "/api/v1/node/" + { + // Encode "node_id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "node_id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.NodeID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + pathParts[2] = "/approve_routes" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeSetApprovedRoutesRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, SetApprovedRoutesOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeSetApprovedRoutesResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// SetPolicy invokes SetPolicy operation. +// +// Set the ACL policy (database policy mode only). +// +// PUT /api/v1/policy +func (c *Client) SetPolicy(ctx context.Context, request *SetPolicyReq) (*SetPolicyOK, error) { + res, err := c.sendSetPolicy(ctx, request) + return res, err +} + +func (c *Client) sendSetPolicy(ctx context.Context, request *SetPolicyReq) (res *SetPolicyOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("SetPolicy"), + semconv.HTTPRequestMethodKey.String("PUT"), + semconv.URLTemplateKey.String("/api/v1/policy"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, SetPolicyOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [1]string + pathParts[0] = "/api/v1/policy" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "PUT", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeSetPolicyRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, SetPolicyOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeSetPolicyResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} + +// SetTags invokes SetTags operation. +// +// Set the tags of a node (converts it to a tagged node). +// +// POST /api/v1/node/{node_id}/tags +func (c *Client) SetTags(ctx context.Context, request *SetTagsReq, params SetTagsParams) (*SetTagsOK, error) { + res, err := c.sendSetTags(ctx, request, params) + return res, err +} + +func (c *Client) sendSetTags(ctx context.Context, request *SetTagsReq, params SetTagsParams) (res *SetTagsOK, err error) { + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("SetTags"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.URLTemplateKey.String("/api/v1/node/{node_id}/tags"), + } + otelAttrs = append(otelAttrs, c.cfg.Attributes...) + + // Run stopwatch. + startTime := time.Now() + defer func() { + // Use floating point division here for higher precision (instead of Millisecond method). + elapsedDuration := time.Since(startTime) + c.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), metric.WithAttributes(otelAttrs...)) + }() + + // Increment request counter. + c.requests.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + + // Start a span for this request. + ctx, span := c.cfg.Tracer.Start(ctx, SetTagsOperation, + trace.WithAttributes(otelAttrs...), + clientSpanKind, + ) + // Track stage for error reporting. + var stage string + defer func() { + if err != nil { + span.RecordError(err) + span.SetStatus(codes.Error, stage) + c.errors.Add(ctx, 1, metric.WithAttributes(otelAttrs...)) + } + span.End() + }() + + stage = "BuildURL" + u := uri.Clone(c.requestURL(ctx)) + var pathParts [3]string + pathParts[0] = "/api/v1/node/" + { + // Encode "node_id" parameter. + e := uri.NewPathEncoder(uri.PathEncoderConfig{ + Param: "node_id", + Style: uri.PathStyleSimple, + Explode: false, + }) + if err := func() error { + return e.EncodeValue(conv.Uint64ToString(params.NodeID)) + }(); err != nil { + return res, errors.Wrap(err, "encode path") + } + encoded, err := e.Result() + if err != nil { + return res, errors.Wrap(err, "encode path") + } + pathParts[1] = encoded + } + pathParts[2] = "/tags" + uri.AddPathParts(u, pathParts[:]...) + + stage = "EncodeRequest" + r, err := ht.NewRequest(ctx, "POST", u) + if err != nil { + return res, errors.Wrap(err, "create request") + } + if err := encodeSetTagsRequest(request, r); err != nil { + return res, errors.Wrap(err, "encode request") + } + + { + type bitset = [1]uint8 + var satisfied bitset + { + stage = "Security:BearerAuth" + switch err := c.securityBearerAuth(ctx, SetTagsOperation, r); { + case err == nil: // if NO error + satisfied[0] |= 1 << 0 + case errors.Is(err, ogenerrors.ErrSkipClientSecurity): + // Skip this security. + default: + return res, errors.Wrap(err, "security \"BearerAuth\"") + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + return res, ogenerrors.ErrSecurityRequirementIsNotSatisfied + } + } + + stage = "SendRequest" + resp, err := c.cfg.Client.Do(r) + if err != nil { + return res, errors.Wrap(err, "do request") + } + body := resp.Body + defer func() { + // Drain the body to EOF before closing, so the underlying + // connection can be reused by the Transport regardless of the + // response status code. See https://github.com/ogen-go/ogen/issues/1670. + _, _ = io.Copy(io.Discard, body) + _ = body.Close() + }() + + stage = "DecodeResponse" + result, err := decodeSetTagsResponse(resp) + if err != nil { + return res, errors.Wrap(err, "decode response") + } + + return result, nil +} diff --git a/gen/api/v1/oas_handlers_gen.go b/gen/api/v1/oas_handlers_gen.go new file mode 100644 index 00000000..feec96f2 --- /dev/null +++ b/gen/api/v1/oas_handlers_gen.go @@ -0,0 +1,5836 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "context" + "net/http" + "time" + + "github.com/go-faster/errors" + ht "github.com/ogen-go/ogen/http" + "github.com/ogen-go/ogen/middleware" + "github.com/ogen-go/ogen/ogenerrors" + "github.com/ogen-go/ogen/otelogen" + "go.opentelemetry.io/otel/attribute" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/metric" + semconv "go.opentelemetry.io/otel/semconv/v1.39.0" + "go.opentelemetry.io/otel/trace" +) + +type codeRecorder struct { + http.ResponseWriter + status int +} + +func (c *codeRecorder) WriteHeader(status int) { + c.status = status + c.ResponseWriter.WriteHeader(status) +} + +func (c *codeRecorder) Unwrap() http.ResponseWriter { + return c.ResponseWriter +} + +// handleAuthApproveRequest handles AuthApprove operation. +// +// Approve a pending auth session. +// +// POST /api/v1/auth/approve +func (s *Server) handleAuthApproveRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("AuthApprove"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/auth/approve"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), AuthApproveOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: AuthApproveOperation, + ID: "AuthApprove", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, AuthApproveOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeAuthApproveRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *AuthApproveOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: AuthApproveOperation, + OperationSummary: "Approve a pending auth session.", + OperationID: "AuthApprove", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *AuthApproveReq + Params = struct{} + Response = *AuthApproveOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.AuthApprove(ctx, request) + return response, err + }, + ) + } else { + err = s.h.AuthApprove(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeAuthApproveResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleAuthRegisterRequest handles AuthRegister operation. +// +// Register a node via an auth id (alias of RegisterNode). +// +// POST /api/v1/auth/register +func (s *Server) handleAuthRegisterRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("AuthRegister"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/auth/register"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), AuthRegisterOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: AuthRegisterOperation, + ID: "AuthRegister", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, AuthRegisterOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeAuthRegisterRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *AuthRegisterOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: AuthRegisterOperation, + OperationSummary: "Register a node via an auth id (alias of RegisterNode).", + OperationID: "AuthRegister", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *AuthRegisterReq + Params = struct{} + Response = *AuthRegisterOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.AuthRegister(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.AuthRegister(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeAuthRegisterResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleAuthRejectRequest handles AuthReject operation. +// +// Reject a pending auth session. +// +// POST /api/v1/auth/reject +func (s *Server) handleAuthRejectRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("AuthReject"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/auth/reject"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), AuthRejectOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: AuthRejectOperation, + ID: "AuthReject", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, AuthRejectOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeAuthRejectRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *AuthRejectOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: AuthRejectOperation, + OperationSummary: "Reject a pending auth session.", + OperationID: "AuthReject", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *AuthRejectReq + Params = struct{} + Response = *AuthRejectOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.AuthReject(ctx, request) + return response, err + }, + ) + } else { + err = s.h.AuthReject(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeAuthRejectResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleBackfillNodeIPsRequest handles BackfillNodeIPs operation. +// +// Backfill missing IP addresses for all nodes. +// +// POST /api/v1/node/backfillips +func (s *Server) handleBackfillNodeIPsRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("BackfillNodeIPs"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/node/backfillips"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), BackfillNodeIPsOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: BackfillNodeIPsOperation, + ID: "BackfillNodeIPs", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, BackfillNodeIPsOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeBackfillNodeIPsParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *BackfillNodeIPsOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: BackfillNodeIPsOperation, + OperationSummary: "Backfill missing IP addresses for all nodes.", + OperationID: "BackfillNodeIPs", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "confirmed", + In: "query", + }: params.Confirmed, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = BackfillNodeIPsParams + Response = *BackfillNodeIPsOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackBackfillNodeIPsParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.BackfillNodeIPs(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.BackfillNodeIPs(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeBackfillNodeIPsResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleCheckPolicyRequest handles CheckPolicy operation. +// +// Validate a policy against live users and nodes without storing it. +// +// POST /api/v1/policy/check +func (s *Server) handleCheckPolicyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CheckPolicy"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/policy/check"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CheckPolicyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CheckPolicyOperation, + ID: "CheckPolicy", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, CheckPolicyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeCheckPolicyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *CheckPolicyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CheckPolicyOperation, + OperationSummary: "Validate a policy against live users and nodes without storing it.", + OperationID: "CheckPolicy", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *CheckPolicyReq + Params = struct{} + Response = *CheckPolicyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.CheckPolicy(ctx, request) + return response, err + }, + ) + } else { + err = s.h.CheckPolicy(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCheckPolicyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleCreateApiKeyRequest handles CreateApiKey operation. +// +// Create an API key. +// +// POST /api/v1/apikey +func (s *Server) handleCreateApiKeyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CreateApiKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/apikey"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CreateApiKeyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CreateApiKeyOperation, + ID: "CreateApiKey", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, CreateApiKeyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeCreateApiKeyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *CreateApiKeyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CreateApiKeyOperation, + OperationSummary: "Create an API key.", + OperationID: "CreateApiKey", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *CreateApiKeyReq + Params = struct{} + Response = *CreateApiKeyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.CreateApiKey(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.CreateApiKey(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCreateApiKeyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleCreatePreAuthKeyRequest handles CreatePreAuthKey operation. +// +// Create a pre-auth key. +// +// POST /api/v1/preauthkey +func (s *Server) handleCreatePreAuthKeyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CreatePreAuthKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/preauthkey"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CreatePreAuthKeyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CreatePreAuthKeyOperation, + ID: "CreatePreAuthKey", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, CreatePreAuthKeyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeCreatePreAuthKeyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *CreatePreAuthKeyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CreatePreAuthKeyOperation, + OperationSummary: "Create a pre-auth key.", + OperationID: "CreatePreAuthKey", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *CreatePreAuthKeyReq + Params = struct{} + Response = *CreatePreAuthKeyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.CreatePreAuthKey(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.CreatePreAuthKey(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCreatePreAuthKeyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleCreateUserRequest handles CreateUser operation. +// +// Create a user. +// +// POST /api/v1/user +func (s *Server) handleCreateUserRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("CreateUser"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/user"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), CreateUserOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: CreateUserOperation, + ID: "CreateUser", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, CreateUserOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeCreateUserRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *CreateUserOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: CreateUserOperation, + OperationSummary: "Create a user.", + OperationID: "CreateUser", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *CreateUserReq + Params = struct{} + Response = *CreateUserOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.CreateUser(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.CreateUser(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeCreateUserResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleDebugCreateNodeRequest handles DebugCreateNode operation. +// +// Create a debug node and cache its registration (testing only). +// +// POST /api/v1/debug/node +func (s *Server) handleDebugCreateNodeRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DebugCreateNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/debug/node"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), DebugCreateNodeOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: DebugCreateNodeOperation, + ID: "DebugCreateNode", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, DebugCreateNodeOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeDebugCreateNodeRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *DebugCreateNodeOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: DebugCreateNodeOperation, + OperationSummary: "Create a debug node and cache its registration (testing only).", + OperationID: "DebugCreateNode", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *DebugCreateNodeReq + Params = struct{} + Response = *DebugCreateNodeOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.DebugCreateNode(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.DebugCreateNode(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeDebugCreateNodeResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleDeleteApiKeyRequest handles DeleteApiKey operation. +// +// Delete an API key by prefix (or id). +// +// DELETE /api/v1/apikey/{prefix} +func (s *Server) handleDeleteApiKeyRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeleteApiKey"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/api/v1/apikey/{prefix}"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), DeleteApiKeyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: DeleteApiKeyOperation, + ID: "DeleteApiKey", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, DeleteApiKeyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeDeleteApiKeyParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *DeleteApiKeyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: DeleteApiKeyOperation, + OperationSummary: "Delete an API key by prefix (or id).", + OperationID: "DeleteApiKey", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "prefix", + In: "path", + }: params.Prefix, + { + Name: "id", + In: "query", + }: params.ID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = DeleteApiKeyParams + Response = *DeleteApiKeyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackDeleteApiKeyParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.DeleteApiKey(ctx, params) + return response, err + }, + ) + } else { + err = s.h.DeleteApiKey(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeDeleteApiKeyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleDeleteNodeRequest handles DeleteNode operation. +// +// Delete a node. +// +// DELETE /api/v1/node/{node_id} +func (s *Server) handleDeleteNodeRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeleteNode"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/api/v1/node/{node_id}"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), DeleteNodeOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: DeleteNodeOperation, + ID: "DeleteNode", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, DeleteNodeOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeDeleteNodeParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *DeleteNodeOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: DeleteNodeOperation, + OperationSummary: "Delete a node.", + OperationID: "DeleteNode", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "node_id", + In: "path", + }: params.NodeID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = DeleteNodeParams + Response = *DeleteNodeOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackDeleteNodeParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.DeleteNode(ctx, params) + return response, err + }, + ) + } else { + err = s.h.DeleteNode(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeDeleteNodeResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleDeletePreAuthKeyRequest handles DeletePreAuthKey operation. +// +// Delete a pre-auth key. +// +// DELETE /api/v1/preauthkey +func (s *Server) handleDeletePreAuthKeyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeletePreAuthKey"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/api/v1/preauthkey"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), DeletePreAuthKeyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: DeletePreAuthKeyOperation, + ID: "DeletePreAuthKey", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, DeletePreAuthKeyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeDeletePreAuthKeyParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *DeletePreAuthKeyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: DeletePreAuthKeyOperation, + OperationSummary: "Delete a pre-auth key.", + OperationID: "DeletePreAuthKey", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "id", + In: "query", + }: params.ID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = DeletePreAuthKeyParams + Response = *DeletePreAuthKeyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackDeletePreAuthKeyParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.DeletePreAuthKey(ctx, params) + return response, err + }, + ) + } else { + err = s.h.DeletePreAuthKey(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeDeletePreAuthKeyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleDeleteUserRequest handles DeleteUser operation. +// +// Delete a user. +// +// DELETE /api/v1/user/{id} +func (s *Server) handleDeleteUserRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("DeleteUser"), + semconv.HTTPRequestMethodKey.String("DELETE"), + semconv.HTTPRouteKey.String("/api/v1/user/{id}"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), DeleteUserOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: DeleteUserOperation, + ID: "DeleteUser", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, DeleteUserOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeDeleteUserParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *DeleteUserOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: DeleteUserOperation, + OperationSummary: "Delete a user.", + OperationID: "DeleteUser", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "id", + In: "path", + }: params.ID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = DeleteUserParams + Response = *DeleteUserOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackDeleteUserParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.DeleteUser(ctx, params) + return response, err + }, + ) + } else { + err = s.h.DeleteUser(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeDeleteUserResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleExpireApiKeyRequest handles ExpireApiKey operation. +// +// Expire an API key by id or prefix. +// +// POST /api/v1/apikey/expire +func (s *Server) handleExpireApiKeyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ExpireApiKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/apikey/expire"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ExpireApiKeyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ExpireApiKeyOperation, + ID: "ExpireApiKey", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, ExpireApiKeyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeExpireApiKeyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *ExpireApiKeyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ExpireApiKeyOperation, + OperationSummary: "Expire an API key by id or prefix.", + OperationID: "ExpireApiKey", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *ExpireApiKeyReq + Params = struct{} + Response = *ExpireApiKeyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.ExpireApiKey(ctx, request) + return response, err + }, + ) + } else { + err = s.h.ExpireApiKey(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeExpireApiKeyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleExpireNodeRequest handles ExpireNode operation. +// +// Expire a node, or disable its expiry. +// +// POST /api/v1/node/{node_id}/expire +func (s *Server) handleExpireNodeRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ExpireNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/node/{node_id}/expire"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ExpireNodeOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ExpireNodeOperation, + ID: "ExpireNode", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, ExpireNodeOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeExpireNodeParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *ExpireNodeOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ExpireNodeOperation, + OperationSummary: "Expire a node, or disable its expiry.", + OperationID: "ExpireNode", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "node_id", + In: "path", + }: params.NodeID, + { + Name: "expiry", + In: "query", + }: params.Expiry, + { + Name: "disable_expiry", + In: "query", + }: params.DisableExpiry, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = ExpireNodeParams + Response = *ExpireNodeOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackExpireNodeParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.ExpireNode(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.ExpireNode(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeExpireNodeResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleExpirePreAuthKeyRequest handles ExpirePreAuthKey operation. +// +// Expire a pre-auth key. +// +// POST /api/v1/preauthkey/expire +func (s *Server) handleExpirePreAuthKeyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ExpirePreAuthKey"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/preauthkey/expire"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ExpirePreAuthKeyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ExpirePreAuthKeyOperation, + ID: "ExpirePreAuthKey", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, ExpirePreAuthKeyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeExpirePreAuthKeyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *ExpirePreAuthKeyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ExpirePreAuthKeyOperation, + OperationSummary: "Expire a pre-auth key.", + OperationID: "ExpirePreAuthKey", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *ExpirePreAuthKeyReq + Params = struct{} + Response = *ExpirePreAuthKeyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + err = s.h.ExpirePreAuthKey(ctx, request) + return response, err + }, + ) + } else { + err = s.h.ExpirePreAuthKey(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeExpirePreAuthKeyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleGetNodeRequest handles GetNode operation. +// +// Get a node by id. +// +// GET /api/v1/node/{node_id} +func (s *Server) handleGetNodeRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("GetNode"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/api/v1/node/{node_id}"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), GetNodeOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: GetNodeOperation, + ID: "GetNode", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, GetNodeOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeGetNodeParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *GetNodeOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: GetNodeOperation, + OperationSummary: "Get a node by id.", + OperationID: "GetNode", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "node_id", + In: "path", + }: params.NodeID, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = GetNodeParams + Response = *GetNodeOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackGetNodeParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.GetNode(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.GetNode(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeGetNodeResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleGetPolicyRequest handles GetPolicy operation. +// +// Get the current ACL policy. +// +// GET /api/v1/policy +func (s *Server) handleGetPolicyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("GetPolicy"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/api/v1/policy"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), GetPolicyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: GetPolicyOperation, + ID: "GetPolicy", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, GetPolicyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + + var response *GetPolicyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: GetPolicyOperation, + OperationSummary: "Get the current ACL policy.", + OperationID: "GetPolicy", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = struct{} + Params = struct{} + Response = *GetPolicyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.GetPolicy(ctx) + return response, err + }, + ) + } else { + response, err = s.h.GetPolicy(ctx) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeGetPolicyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleHealthRequest handles Health operation. +// +// Report server health, including database connectivity. +// +// GET /api/v1/health +func (s *Server) handleHealthRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("Health"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/api/v1/health"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), HealthOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: HealthOperation, + ID: "Health", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, HealthOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + + var response *HealthOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: HealthOperation, + OperationSummary: "Report server health, including database connectivity.", + OperationID: "Health", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = struct{} + Params = struct{} + Response = *HealthOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.Health(ctx) + return response, err + }, + ) + } else { + response, err = s.h.Health(ctx) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeHealthResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleListApiKeysRequest handles ListApiKeys operation. +// +// List all API keys. +// +// GET /api/v1/apikey +func (s *Server) handleListApiKeysRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListApiKeys"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/api/v1/apikey"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ListApiKeysOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ListApiKeysOperation, + ID: "ListApiKeys", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, ListApiKeysOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + + var response *ListApiKeysOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ListApiKeysOperation, + OperationSummary: "List all API keys.", + OperationID: "ListApiKeys", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = struct{} + Params = struct{} + Response = *ListApiKeysOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.ListApiKeys(ctx) + return response, err + }, + ) + } else { + response, err = s.h.ListApiKeys(ctx) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeListApiKeysResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleListNodesRequest handles ListNodes operation. +// +// List nodes, optionally filtered by user. +// +// GET /api/v1/node +func (s *Server) handleListNodesRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListNodes"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/api/v1/node"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ListNodesOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ListNodesOperation, + ID: "ListNodes", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, ListNodesOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeListNodesParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *ListNodesOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ListNodesOperation, + OperationSummary: "List nodes, optionally filtered by user.", + OperationID: "ListNodes", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "user", + In: "query", + }: params.User, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = ListNodesParams + Response = *ListNodesOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackListNodesParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.ListNodes(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.ListNodes(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeListNodesResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleListPreAuthKeysRequest handles ListPreAuthKeys operation. +// +// List all pre-auth keys. +// +// GET /api/v1/preauthkey +func (s *Server) handleListPreAuthKeysRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListPreAuthKeys"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/api/v1/preauthkey"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ListPreAuthKeysOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ListPreAuthKeysOperation, + ID: "ListPreAuthKeys", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, ListPreAuthKeysOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + + var response *ListPreAuthKeysOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ListPreAuthKeysOperation, + OperationSummary: "List all pre-auth keys.", + OperationID: "ListPreAuthKeys", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = struct{} + Params = struct{} + Response = *ListPreAuthKeysOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.ListPreAuthKeys(ctx) + return response, err + }, + ) + } else { + response, err = s.h.ListPreAuthKeys(ctx) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeListPreAuthKeysResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleListUsersRequest handles ListUsers operation. +// +// List users, optionally filtered by id, name, or email. +// +// GET /api/v1/user +func (s *Server) handleListUsersRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("ListUsers"), + semconv.HTTPRequestMethodKey.String("GET"), + semconv.HTTPRouteKey.String("/api/v1/user"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), ListUsersOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: ListUsersOperation, + ID: "ListUsers", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, ListUsersOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeListUsersParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *ListUsersOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: ListUsersOperation, + OperationSummary: "List users, optionally filtered by id, name, or email.", + OperationID: "ListUsers", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "id", + In: "query", + }: params.ID, + { + Name: "name", + In: "query", + }: params.Name, + { + Name: "email", + In: "query", + }: params.Email, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = ListUsersParams + Response = *ListUsersOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackListUsersParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.ListUsers(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.ListUsers(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeListUsersResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleRegisterNodeRequest handles RegisterNode operation. +// +// Register a node to a user using a registration id. +// +// POST /api/v1/node/register +func (s *Server) handleRegisterNodeRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("RegisterNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/node/register"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), RegisterNodeOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: RegisterNodeOperation, + ID: "RegisterNode", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, RegisterNodeOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeRegisterNodeParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *RegisterNodeOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: RegisterNodeOperation, + OperationSummary: "Register a node to a user using a registration id.", + OperationID: "RegisterNode", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "user", + In: "query", + }: params.User, + { + Name: "key", + In: "query", + }: params.Key, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = RegisterNodeParams + Response = *RegisterNodeOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackRegisterNodeParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.RegisterNode(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.RegisterNode(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeRegisterNodeResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleRenameNodeRequest handles RenameNode operation. +// +// Rename a node. +// +// POST /api/v1/node/{node_id}/rename/{new_name} +func (s *Server) handleRenameNodeRequest(args [2]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("RenameNode"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/node/{node_id}/rename/{new_name}"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), RenameNodeOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: RenameNodeOperation, + ID: "RenameNode", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, RenameNodeOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeRenameNodeParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *RenameNodeOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: RenameNodeOperation, + OperationSummary: "Rename a node.", + OperationID: "RenameNode", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "node_id", + In: "path", + }: params.NodeID, + { + Name: "new_name", + In: "path", + }: params.NewName, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = RenameNodeParams + Response = *RenameNodeOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackRenameNodeParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.RenameNode(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.RenameNode(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeRenameNodeResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleRenameUserRequest handles RenameUser operation. +// +// Rename a user. +// +// POST /api/v1/user/{old_id}/rename/{new_name} +func (s *Server) handleRenameUserRequest(args [2]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("RenameUser"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/user/{old_id}/rename/{new_name}"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), RenameUserOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: RenameUserOperation, + ID: "RenameUser", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, RenameUserOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeRenameUserParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + + var response *RenameUserOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: RenameUserOperation, + OperationSummary: "Rename a user.", + OperationID: "RenameUser", + Body: nil, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "old_id", + In: "path", + }: params.OldID, + { + Name: "new_name", + In: "path", + }: params.NewName, + }, + Raw: r, + } + + type ( + Request = struct{} + Params = RenameUserParams + Response = *RenameUserOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackRenameUserParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.RenameUser(ctx, params) + return response, err + }, + ) + } else { + response, err = s.h.RenameUser(ctx, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeRenameUserResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleSetApprovedRoutesRequest handles SetApprovedRoutes operation. +// +// Set the approved subnet routes of a node. +// +// POST /api/v1/node/{node_id}/approve_routes +func (s *Server) handleSetApprovedRoutesRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("SetApprovedRoutes"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/node/{node_id}/approve_routes"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), SetApprovedRoutesOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: SetApprovedRoutesOperation, + ID: "SetApprovedRoutes", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, SetApprovedRoutesOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeSetApprovedRoutesParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + request, rawBody, close, err := s.decodeSetApprovedRoutesRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *SetApprovedRoutesOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: SetApprovedRoutesOperation, + OperationSummary: "Set the approved subnet routes of a node.", + OperationID: "SetApprovedRoutes", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "node_id", + In: "path", + }: params.NodeID, + }, + Raw: r, + } + + type ( + Request = *SetApprovedRoutesReq + Params = SetApprovedRoutesParams + Response = *SetApprovedRoutesOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackSetApprovedRoutesParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.SetApprovedRoutes(ctx, request, params) + return response, err + }, + ) + } else { + response, err = s.h.SetApprovedRoutes(ctx, request, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeSetApprovedRoutesResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleSetPolicyRequest handles SetPolicy operation. +// +// Set the ACL policy (database policy mode only). +// +// PUT /api/v1/policy +func (s *Server) handleSetPolicyRequest(args [0]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("SetPolicy"), + semconv.HTTPRequestMethodKey.String("PUT"), + semconv.HTTPRouteKey.String("/api/v1/policy"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), SetPolicyOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: SetPolicyOperation, + ID: "SetPolicy", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, SetPolicyOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + + var rawBody []byte + request, rawBody, close, err := s.decodeSetPolicyRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *SetPolicyOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: SetPolicyOperation, + OperationSummary: "Set the ACL policy (database policy mode only).", + OperationID: "SetPolicy", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{}, + Raw: r, + } + + type ( + Request = *SetPolicyReq + Params = struct{} + Response = *SetPolicyOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + nil, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.SetPolicy(ctx, request) + return response, err + }, + ) + } else { + response, err = s.h.SetPolicy(ctx, request) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeSetPolicyResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} + +// handleSetTagsRequest handles SetTags operation. +// +// Set the tags of a node (converts it to a tagged node). +// +// POST /api/v1/node/{node_id}/tags +func (s *Server) handleSetTagsRequest(args [1]string, argsEscaped bool, w http.ResponseWriter, r *http.Request) { + statusWriter := &codeRecorder{ResponseWriter: w} + w = statusWriter + otelAttrs := []attribute.KeyValue{ + otelogen.OperationID("SetTags"), + semconv.HTTPRequestMethodKey.String("POST"), + semconv.HTTPRouteKey.String("/api/v1/node/{node_id}/tags"), + } + // Add attributes from config. + otelAttrs = append(otelAttrs, s.cfg.Attributes...) + + // Start a span for this request. + ctx, span := s.cfg.Tracer.Start(r.Context(), SetTagsOperation, + trace.WithAttributes(otelAttrs...), + serverSpanKind, + ) + defer span.End() + + // Add Labeler to context. + labeler := &Labeler{attrs: otelAttrs} + ctx = contextWithLabeler(ctx, labeler) + + // Run stopwatch. + startTime := time.Now() + defer func() { + elapsedDuration := time.Since(startTime) + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + code := statusWriter.status + if code != 0 { + codeAttr := semconv.HTTPResponseStatusCode(code) + attrs = append(attrs, codeAttr) + span.SetAttributes(attrs...) + } + attrOpt := metric.WithAttributes(attrs...) + + // Increment request counter. + s.requests.Add(ctx, 1, attrOpt) + + // Use floating point division here for higher precision (instead of Millisecond method). + s.duration.Record(ctx, float64(elapsedDuration)/float64(time.Millisecond), attrOpt) + }() + + var ( + recordError = func(stage string, err error) { + span.RecordError(err) + + // https://opentelemetry.io/docs/specs/semconv/http/http-spans/#status + // Span Status MUST be left unset if HTTP status code was in the 1xx, 2xx or 3xx ranges, + // unless there was another error (e.g., network error receiving the response body; or 3xx codes with + // max redirects exceeded), in which case status MUST be set to Error. + code := statusWriter.status + if code < 100 || code >= 500 { + span.SetStatus(codes.Error, stage) + } + + attrSet := labeler.AttributeSet() + attrs := attrSet.ToSlice() + if code != 0 { + attrs = append(attrs, semconv.HTTPResponseStatusCode(code)) + } + + s.errors.Add(ctx, 1, metric.WithAttributes(attrs...)) + } + err error + opErrContext = ogenerrors.OperationContext{ + Name: SetTagsOperation, + ID: "SetTags", + } + ) + { + type bitset = [1]uint8 + var satisfied bitset + { + sctx, ok, err := s.securityBearerAuth(ctx, SetTagsOperation, r) + if err != nil { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Security: "BearerAuth", + Err: err, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security:BearerAuth", err) + } + return + } + if ok { + satisfied[0] |= 1 << 0 + ctx = sctx + } + } + + if ok := func() bool { + nextRequirement: + for _, requirement := range []bitset{ + {0b00000001}, + } { + for i, mask := range requirement { + if satisfied[i]&mask != mask { + continue nextRequirement + } + } + return true + } + return false + }(); !ok { + err = &ogenerrors.SecurityError{ + OperationContext: opErrContext, + Err: ogenerrors.ErrSecurityRequirementIsNotSatisfied, + } + if encodeErr := encodeErrorResponse(s.h.NewError(ctx, err), w, span); encodeErr != nil { + defer recordError("Security", err) + } + return + } + } + params, err := decodeSetTagsParams(args, argsEscaped, r) + if err != nil { + err = &ogenerrors.DecodeParamsError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeParams", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + + var rawBody []byte + request, rawBody, close, err := s.decodeSetTagsRequest(r) + if err != nil { + err = &ogenerrors.DecodeRequestError{ + OperationContext: opErrContext, + Err: err, + } + defer recordError("DecodeRequest", err) + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + defer func() { + if err := close(); err != nil { + recordError("CloseRequest", err) + } + }() + + var response *SetTagsOK + if m := s.cfg.Middleware; m != nil { + mreq := middleware.Request{ + Context: ctx, + OperationName: SetTagsOperation, + OperationSummary: "Set the tags of a node (converts it to a tagged node).", + OperationID: "SetTags", + Body: request, + RawBody: rawBody, + Params: middleware.Parameters{ + { + Name: "node_id", + In: "path", + }: params.NodeID, + }, + Raw: r, + } + + type ( + Request = *SetTagsReq + Params = SetTagsParams + Response = *SetTagsOK + ) + response, err = middleware.HookMiddleware[ + Request, + Params, + Response, + ]( + m, + mreq, + unpackSetTagsParams, + func(ctx context.Context, request Request, params Params) (response Response, err error) { + response, err = s.h.SetTags(ctx, request, params) + return response, err + }, + ) + } else { + response, err = s.h.SetTags(ctx, request, params) + } + if err != nil { + if errRes, ok := errors.Into[*ErrorStatusCode](err); ok { + if err := encodeErrorResponse(errRes, w, span); err != nil { + defer recordError("Internal", err) + } + return + } + if errors.Is(err, ht.ErrNotImplemented) { + s.cfg.ErrorHandler(ctx, w, r, err) + return + } + if err := encodeErrorResponse(s.h.NewError(ctx, err), w, span); err != nil { + defer recordError("Internal", err) + } + return + } + + if err := encodeSetTagsResponse(response, w, span); err != nil { + defer recordError("EncodeResponse", err) + if !errors.Is(err, ht.ErrInternalServerErrorResponse) { + s.cfg.ErrorHandler(ctx, w, r, err) + } + return + } +} diff --git a/gen/api/v1/oas_json_gen.go b/gen/api/v1/oas_json_gen.go new file mode 100644 index 00000000..2c8de3f9 --- /dev/null +++ b/gen/api/v1/oas_json_gen.go @@ -0,0 +1,4292 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "time" + + "github.com/go-faster/errors" + "github.com/go-faster/jx" + "github.com/ogen-go/ogen/json" +) + +// Encode implements json.Marshaler. +func (s *ApiKey) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ApiKey) encodeFields(e *jx.Encoder) { + { + if s.ID.Set { + e.FieldStart("id") + s.ID.Encode(e) + } + } + { + if s.Prefix.Set { + e.FieldStart("prefix") + s.Prefix.Encode(e) + } + } + { + if s.Expiration.Set { + e.FieldStart("expiration") + s.Expiration.Encode(e, json.EncodeDateTime) + } + } + { + if s.CreatedAt.Set { + e.FieldStart("createdAt") + s.CreatedAt.Encode(e, json.EncodeDateTime) + } + } + { + if s.LastSeen.Set { + e.FieldStart("lastSeen") + s.LastSeen.Encode(e, json.EncodeDateTime) + } + } +} + +var jsonFieldsNameOfApiKey = [5]string{ + 0: "id", + 1: "prefix", + 2: "expiration", + 3: "createdAt", + 4: "lastSeen", +} + +// Decode decodes ApiKey from json. +func (s *ApiKey) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ApiKey to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "id": + if err := func() error { + s.ID.Reset() + if err := s.ID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"id\"") + } + case "prefix": + if err := func() error { + s.Prefix.Reset() + if err := s.Prefix.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"prefix\"") + } + case "expiration": + if err := func() error { + s.Expiration.Reset() + if err := s.Expiration.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"expiration\"") + } + case "createdAt": + if err := func() error { + s.CreatedAt.Reset() + if err := s.CreatedAt.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"createdAt\"") + } + case "lastSeen": + if err := func() error { + s.LastSeen.Reset() + if err := s.LastSeen.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"lastSeen\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ApiKey") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ApiKey) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ApiKey) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *AuthApproveOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *AuthApproveOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfAuthApproveOK = [0]string{} + +// Decode decodes AuthApproveOK from json. +func (s *AuthApproveOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuthApproveOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode AuthApproveOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *AuthApproveOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuthApproveOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *AuthApproveReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *AuthApproveReq) encodeFields(e *jx.Encoder) { + { + if s.AuthId.Set { + e.FieldStart("authId") + s.AuthId.Encode(e) + } + } +} + +var jsonFieldsNameOfAuthApproveReq = [1]string{ + 0: "authId", +} + +// Decode decodes AuthApproveReq from json. +func (s *AuthApproveReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuthApproveReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "authId": + if err := func() error { + s.AuthId.Reset() + if err := s.AuthId.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"authId\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode AuthApproveReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *AuthApproveReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuthApproveReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *AuthRegisterOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *AuthRegisterOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfAuthRegisterOK = [1]string{ + 0: "node", +} + +// Decode decodes AuthRegisterOK from json. +func (s *AuthRegisterOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuthRegisterOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode AuthRegisterOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *AuthRegisterOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuthRegisterOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *AuthRegisterReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *AuthRegisterReq) encodeFields(e *jx.Encoder) { + { + if s.User.Set { + e.FieldStart("user") + s.User.Encode(e) + } + } + { + if s.AuthId.Set { + e.FieldStart("authId") + s.AuthId.Encode(e) + } + } +} + +var jsonFieldsNameOfAuthRegisterReq = [2]string{ + 0: "user", + 1: "authId", +} + +// Decode decodes AuthRegisterReq from json. +func (s *AuthRegisterReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuthRegisterReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "user": + if err := func() error { + s.User.Reset() + if err := s.User.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"user\"") + } + case "authId": + if err := func() error { + s.AuthId.Reset() + if err := s.AuthId.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"authId\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode AuthRegisterReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *AuthRegisterReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuthRegisterReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *AuthRejectOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *AuthRejectOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfAuthRejectOK = [0]string{} + +// Decode decodes AuthRejectOK from json. +func (s *AuthRejectOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuthRejectOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode AuthRejectOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *AuthRejectOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuthRejectOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *AuthRejectReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *AuthRejectReq) encodeFields(e *jx.Encoder) { + { + if s.AuthId.Set { + e.FieldStart("authId") + s.AuthId.Encode(e) + } + } +} + +var jsonFieldsNameOfAuthRejectReq = [1]string{ + 0: "authId", +} + +// Decode decodes AuthRejectReq from json. +func (s *AuthRejectReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode AuthRejectReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "authId": + if err := func() error { + s.AuthId.Reset() + if err := s.AuthId.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"authId\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode AuthRejectReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *AuthRejectReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *AuthRejectReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *BackfillNodeIPsOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *BackfillNodeIPsOK) encodeFields(e *jx.Encoder) { + { + if s.Changes != nil { + e.FieldStart("changes") + e.ArrStart() + for _, elem := range s.Changes { + e.Str(elem) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfBackfillNodeIPsOK = [1]string{ + 0: "changes", +} + +// Decode decodes BackfillNodeIPsOK from json. +func (s *BackfillNodeIPsOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode BackfillNodeIPsOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "changes": + if err := func() error { + s.Changes = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.Changes = append(s.Changes, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"changes\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode BackfillNodeIPsOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *BackfillNodeIPsOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *BackfillNodeIPsOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CheckPolicyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CheckPolicyOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfCheckPolicyOK = [0]string{} + +// Decode decodes CheckPolicyOK from json. +func (s *CheckPolicyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CheckPolicyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode CheckPolicyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CheckPolicyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CheckPolicyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CheckPolicyReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CheckPolicyReq) encodeFields(e *jx.Encoder) { + { + if s.Policy.Set { + e.FieldStart("policy") + s.Policy.Encode(e) + } + } +} + +var jsonFieldsNameOfCheckPolicyReq = [1]string{ + 0: "policy", +} + +// Decode decodes CheckPolicyReq from json. +func (s *CheckPolicyReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CheckPolicyReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "policy": + if err := func() error { + s.Policy.Reset() + if err := s.Policy.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"policy\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode CheckPolicyReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CheckPolicyReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CheckPolicyReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CreateApiKeyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CreateApiKeyOK) encodeFields(e *jx.Encoder) { + { + if s.ApiKey.Set { + e.FieldStart("apiKey") + s.ApiKey.Encode(e) + } + } +} + +var jsonFieldsNameOfCreateApiKeyOK = [1]string{ + 0: "apiKey", +} + +// Decode decodes CreateApiKeyOK from json. +func (s *CreateApiKeyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CreateApiKeyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "apiKey": + if err := func() error { + s.ApiKey.Reset() + if err := s.ApiKey.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"apiKey\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode CreateApiKeyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CreateApiKeyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CreateApiKeyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CreateApiKeyReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CreateApiKeyReq) encodeFields(e *jx.Encoder) { + { + if s.Expiration.Set { + e.FieldStart("expiration") + s.Expiration.Encode(e, json.EncodeDateTime) + } + } +} + +var jsonFieldsNameOfCreateApiKeyReq = [1]string{ + 0: "expiration", +} + +// Decode decodes CreateApiKeyReq from json. +func (s *CreateApiKeyReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CreateApiKeyReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "expiration": + if err := func() error { + s.Expiration.Reset() + if err := s.Expiration.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"expiration\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode CreateApiKeyReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CreateApiKeyReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CreateApiKeyReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CreatePreAuthKeyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CreatePreAuthKeyOK) encodeFields(e *jx.Encoder) { + { + if s.PreAuthKey.Set { + e.FieldStart("preAuthKey") + s.PreAuthKey.Encode(e) + } + } +} + +var jsonFieldsNameOfCreatePreAuthKeyOK = [1]string{ + 0: "preAuthKey", +} + +// Decode decodes CreatePreAuthKeyOK from json. +func (s *CreatePreAuthKeyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CreatePreAuthKeyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "preAuthKey": + if err := func() error { + s.PreAuthKey.Reset() + if err := s.PreAuthKey.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"preAuthKey\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode CreatePreAuthKeyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CreatePreAuthKeyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CreatePreAuthKeyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CreatePreAuthKeyReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CreatePreAuthKeyReq) encodeFields(e *jx.Encoder) { + { + if s.User.Set { + e.FieldStart("user") + s.User.Encode(e) + } + } + { + if s.Reusable.Set { + e.FieldStart("reusable") + s.Reusable.Encode(e) + } + } + { + if s.Ephemeral.Set { + e.FieldStart("ephemeral") + s.Ephemeral.Encode(e) + } + } + { + if s.Expiration.Set { + e.FieldStart("expiration") + s.Expiration.Encode(e, json.EncodeDateTime) + } + } + { + if s.AclTags != nil { + e.FieldStart("aclTags") + e.ArrStart() + for _, elem := range s.AclTags { + e.Str(elem) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfCreatePreAuthKeyReq = [5]string{ + 0: "user", + 1: "reusable", + 2: "ephemeral", + 3: "expiration", + 4: "aclTags", +} + +// Decode decodes CreatePreAuthKeyReq from json. +func (s *CreatePreAuthKeyReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CreatePreAuthKeyReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "user": + if err := func() error { + s.User.Reset() + if err := s.User.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"user\"") + } + case "reusable": + if err := func() error { + s.Reusable.Reset() + if err := s.Reusable.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"reusable\"") + } + case "ephemeral": + if err := func() error { + s.Ephemeral.Reset() + if err := s.Ephemeral.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ephemeral\"") + } + case "expiration": + if err := func() error { + s.Expiration.Reset() + if err := s.Expiration.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"expiration\"") + } + case "aclTags": + if err := func() error { + s.AclTags = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.AclTags = append(s.AclTags, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"aclTags\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode CreatePreAuthKeyReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CreatePreAuthKeyReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CreatePreAuthKeyReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CreateUserOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CreateUserOK) encodeFields(e *jx.Encoder) { + { + if s.User.Set { + e.FieldStart("user") + s.User.Encode(e) + } + } +} + +var jsonFieldsNameOfCreateUserOK = [1]string{ + 0: "user", +} + +// Decode decodes CreateUserOK from json. +func (s *CreateUserOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CreateUserOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "user": + if err := func() error { + s.User.Reset() + if err := s.User.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"user\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode CreateUserOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CreateUserOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CreateUserOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *CreateUserReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *CreateUserReq) encodeFields(e *jx.Encoder) { + { + if s.Name.Set { + e.FieldStart("name") + s.Name.Encode(e) + } + } + { + if s.DisplayName.Set { + e.FieldStart("displayName") + s.DisplayName.Encode(e) + } + } + { + if s.Email.Set { + e.FieldStart("email") + s.Email.Encode(e) + } + } + { + if s.PictureUrl.Set { + e.FieldStart("pictureUrl") + s.PictureUrl.Encode(e) + } + } +} + +var jsonFieldsNameOfCreateUserReq = [4]string{ + 0: "name", + 1: "displayName", + 2: "email", + 3: "pictureUrl", +} + +// Decode decodes CreateUserReq from json. +func (s *CreateUserReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode CreateUserReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "name": + if err := func() error { + s.Name.Reset() + if err := s.Name.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"name\"") + } + case "displayName": + if err := func() error { + s.DisplayName.Reset() + if err := s.DisplayName.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"displayName\"") + } + case "email": + if err := func() error { + s.Email.Reset() + if err := s.Email.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"email\"") + } + case "pictureUrl": + if err := func() error { + s.PictureUrl.Reset() + if err := s.PictureUrl.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"pictureUrl\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode CreateUserReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *CreateUserReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *CreateUserReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *DebugCreateNodeOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *DebugCreateNodeOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfDebugCreateNodeOK = [1]string{ + 0: "node", +} + +// Decode decodes DebugCreateNodeOK from json. +func (s *DebugCreateNodeOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode DebugCreateNodeOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode DebugCreateNodeOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *DebugCreateNodeOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *DebugCreateNodeOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *DebugCreateNodeReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *DebugCreateNodeReq) encodeFields(e *jx.Encoder) { + { + if s.User.Set { + e.FieldStart("user") + s.User.Encode(e) + } + } + { + if s.Key.Set { + e.FieldStart("key") + s.Key.Encode(e) + } + } + { + if s.Name.Set { + e.FieldStart("name") + s.Name.Encode(e) + } + } + { + if s.Routes != nil { + e.FieldStart("routes") + e.ArrStart() + for _, elem := range s.Routes { + e.Str(elem) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfDebugCreateNodeReq = [4]string{ + 0: "user", + 1: "key", + 2: "name", + 3: "routes", +} + +// Decode decodes DebugCreateNodeReq from json. +func (s *DebugCreateNodeReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode DebugCreateNodeReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "user": + if err := func() error { + s.User.Reset() + if err := s.User.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"user\"") + } + case "key": + if err := func() error { + s.Key.Reset() + if err := s.Key.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"key\"") + } + case "name": + if err := func() error { + s.Name.Reset() + if err := s.Name.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"name\"") + } + case "routes": + if err := func() error { + s.Routes = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.Routes = append(s.Routes, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"routes\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode DebugCreateNodeReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *DebugCreateNodeReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *DebugCreateNodeReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *DeleteApiKeyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *DeleteApiKeyOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfDeleteApiKeyOK = [0]string{} + +// Decode decodes DeleteApiKeyOK from json. +func (s *DeleteApiKeyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode DeleteApiKeyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode DeleteApiKeyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *DeleteApiKeyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *DeleteApiKeyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *DeleteNodeOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *DeleteNodeOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfDeleteNodeOK = [0]string{} + +// Decode decodes DeleteNodeOK from json. +func (s *DeleteNodeOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode DeleteNodeOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode DeleteNodeOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *DeleteNodeOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *DeleteNodeOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *DeletePreAuthKeyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *DeletePreAuthKeyOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfDeletePreAuthKeyOK = [0]string{} + +// Decode decodes DeletePreAuthKeyOK from json. +func (s *DeletePreAuthKeyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode DeletePreAuthKeyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode DeletePreAuthKeyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *DeletePreAuthKeyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *DeletePreAuthKeyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *DeleteUserOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *DeleteUserOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfDeleteUserOK = [0]string{} + +// Decode decodes DeleteUserOK from json. +func (s *DeleteUserOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode DeleteUserOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode DeleteUserOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *DeleteUserOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *DeleteUserOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ExpireApiKeyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ExpireApiKeyOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfExpireApiKeyOK = [0]string{} + +// Decode decodes ExpireApiKeyOK from json. +func (s *ExpireApiKeyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ExpireApiKeyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode ExpireApiKeyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ExpireApiKeyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ExpireApiKeyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ExpireApiKeyReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ExpireApiKeyReq) encodeFields(e *jx.Encoder) { + { + if s.Prefix.Set { + e.FieldStart("prefix") + s.Prefix.Encode(e) + } + } + { + if s.ID.Set { + e.FieldStart("id") + s.ID.Encode(e) + } + } +} + +var jsonFieldsNameOfExpireApiKeyReq = [2]string{ + 0: "prefix", + 1: "id", +} + +// Decode decodes ExpireApiKeyReq from json. +func (s *ExpireApiKeyReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ExpireApiKeyReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "prefix": + if err := func() error { + s.Prefix.Reset() + if err := s.Prefix.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"prefix\"") + } + case "id": + if err := func() error { + s.ID.Reset() + if err := s.ID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"id\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ExpireApiKeyReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ExpireApiKeyReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ExpireApiKeyReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ExpireNodeOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ExpireNodeOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfExpireNodeOK = [1]string{ + 0: "node", +} + +// Decode decodes ExpireNodeOK from json. +func (s *ExpireNodeOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ExpireNodeOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ExpireNodeOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ExpireNodeOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ExpireNodeOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ExpirePreAuthKeyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ExpirePreAuthKeyOK) encodeFields(e *jx.Encoder) { +} + +var jsonFieldsNameOfExpirePreAuthKeyOK = [0]string{} + +// Decode decodes ExpirePreAuthKeyOK from json. +func (s *ExpirePreAuthKeyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ExpirePreAuthKeyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + default: + return d.Skip() + } + }); err != nil { + return errors.Wrap(err, "decode ExpirePreAuthKeyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ExpirePreAuthKeyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ExpirePreAuthKeyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ExpirePreAuthKeyReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ExpirePreAuthKeyReq) encodeFields(e *jx.Encoder) { + { + if s.ID.Set { + e.FieldStart("id") + s.ID.Encode(e) + } + } +} + +var jsonFieldsNameOfExpirePreAuthKeyReq = [1]string{ + 0: "id", +} + +// Decode decodes ExpirePreAuthKeyReq from json. +func (s *ExpirePreAuthKeyReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ExpirePreAuthKeyReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "id": + if err := func() error { + s.ID.Reset() + if err := s.ID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"id\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ExpirePreAuthKeyReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ExpirePreAuthKeyReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ExpirePreAuthKeyReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *GetNodeOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *GetNodeOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfGetNodeOK = [1]string{ + 0: "node", +} + +// Decode decodes GetNodeOK from json. +func (s *GetNodeOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode GetNodeOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode GetNodeOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *GetNodeOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *GetNodeOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *GetPolicyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *GetPolicyOK) encodeFields(e *jx.Encoder) { + { + if s.Policy.Set { + e.FieldStart("policy") + s.Policy.Encode(e) + } + } + { + if s.UpdatedAt.Set { + e.FieldStart("updatedAt") + s.UpdatedAt.Encode(e, json.EncodeDateTime) + } + } +} + +var jsonFieldsNameOfGetPolicyOK = [2]string{ + 0: "policy", + 1: "updatedAt", +} + +// Decode decodes GetPolicyOK from json. +func (s *GetPolicyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode GetPolicyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "policy": + if err := func() error { + s.Policy.Reset() + if err := s.Policy.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"policy\"") + } + case "updatedAt": + if err := func() error { + s.UpdatedAt.Reset() + if err := s.UpdatedAt.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"updatedAt\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode GetPolicyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *GetPolicyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *GetPolicyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *HealthOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *HealthOK) encodeFields(e *jx.Encoder) { + { + if s.DatabaseConnectivity.Set { + e.FieldStart("databaseConnectivity") + s.DatabaseConnectivity.Encode(e) + } + } +} + +var jsonFieldsNameOfHealthOK = [1]string{ + 0: "databaseConnectivity", +} + +// Decode decodes HealthOK from json. +func (s *HealthOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode HealthOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "databaseConnectivity": + if err := func() error { + s.DatabaseConnectivity.Reset() + if err := s.DatabaseConnectivity.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"databaseConnectivity\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode HealthOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *HealthOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *HealthOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ListApiKeysOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ListApiKeysOK) encodeFields(e *jx.Encoder) { + { + if s.ApiKeys != nil { + e.FieldStart("apiKeys") + e.ArrStart() + for _, elem := range s.ApiKeys { + elem.Encode(e) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfListApiKeysOK = [1]string{ + 0: "apiKeys", +} + +// Decode decodes ListApiKeysOK from json. +func (s *ListApiKeysOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ListApiKeysOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "apiKeys": + if err := func() error { + s.ApiKeys = make([]ApiKey, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem ApiKey + if err := elem.Decode(d); err != nil { + return err + } + s.ApiKeys = append(s.ApiKeys, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"apiKeys\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ListApiKeysOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ListApiKeysOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ListApiKeysOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ListNodesOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ListNodesOK) encodeFields(e *jx.Encoder) { + { + if s.Nodes != nil { + e.FieldStart("nodes") + e.ArrStart() + for _, elem := range s.Nodes { + elem.Encode(e) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfListNodesOK = [1]string{ + 0: "nodes", +} + +// Decode decodes ListNodesOK from json. +func (s *ListNodesOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ListNodesOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "nodes": + if err := func() error { + s.Nodes = make([]Node, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem Node + if err := elem.Decode(d); err != nil { + return err + } + s.Nodes = append(s.Nodes, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"nodes\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ListNodesOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ListNodesOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ListNodesOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ListPreAuthKeysOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ListPreAuthKeysOK) encodeFields(e *jx.Encoder) { + { + if s.PreAuthKeys != nil { + e.FieldStart("preAuthKeys") + e.ArrStart() + for _, elem := range s.PreAuthKeys { + elem.Encode(e) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfListPreAuthKeysOK = [1]string{ + 0: "preAuthKeys", +} + +// Decode decodes ListPreAuthKeysOK from json. +func (s *ListPreAuthKeysOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ListPreAuthKeysOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "preAuthKeys": + if err := func() error { + s.PreAuthKeys = make([]PreAuthKey, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem PreAuthKey + if err := elem.Decode(d); err != nil { + return err + } + s.PreAuthKeys = append(s.PreAuthKeys, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"preAuthKeys\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ListPreAuthKeysOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ListPreAuthKeysOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ListPreAuthKeysOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *ListUsersOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *ListUsersOK) encodeFields(e *jx.Encoder) { + { + if s.Users != nil { + e.FieldStart("users") + e.ArrStart() + for _, elem := range s.Users { + elem.Encode(e) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfListUsersOK = [1]string{ + 0: "users", +} + +// Decode decodes ListUsersOK from json. +func (s *ListUsersOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode ListUsersOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "users": + if err := func() error { + s.Users = make([]User, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem User + if err := elem.Decode(d); err != nil { + return err + } + s.Users = append(s.Users, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"users\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode ListUsersOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *ListUsersOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *ListUsersOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *Node) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *Node) encodeFields(e *jx.Encoder) { + { + if s.ID.Set { + e.FieldStart("id") + s.ID.Encode(e) + } + } + { + if s.MachineKey.Set { + e.FieldStart("machineKey") + s.MachineKey.Encode(e) + } + } + { + if s.NodeKey.Set { + e.FieldStart("nodeKey") + s.NodeKey.Encode(e) + } + } + { + if s.DiscoKey.Set { + e.FieldStart("discoKey") + s.DiscoKey.Encode(e) + } + } + { + if s.IpAddresses != nil { + e.FieldStart("ipAddresses") + e.ArrStart() + for _, elem := range s.IpAddresses { + e.Str(elem) + } + e.ArrEnd() + } + } + { + if s.Name.Set { + e.FieldStart("name") + s.Name.Encode(e) + } + } + { + if s.User.Set { + e.FieldStart("user") + s.User.Encode(e) + } + } + { + if s.LastSeen.Set { + e.FieldStart("lastSeen") + s.LastSeen.Encode(e, json.EncodeDateTime) + } + } + { + if s.Expiry.Set { + e.FieldStart("expiry") + s.Expiry.Encode(e, json.EncodeDateTime) + } + } + { + if s.PreAuthKey.Set { + e.FieldStart("preAuthKey") + s.PreAuthKey.Encode(e) + } + } + { + if s.CreatedAt.Set { + e.FieldStart("createdAt") + s.CreatedAt.Encode(e, json.EncodeDateTime) + } + } + { + if s.RegisterMethod.Set { + e.FieldStart("registerMethod") + s.RegisterMethod.Encode(e) + } + } + { + if s.GivenName.Set { + e.FieldStart("givenName") + s.GivenName.Encode(e) + } + } + { + if s.Online.Set { + e.FieldStart("online") + s.Online.Encode(e) + } + } + { + if s.ApprovedRoutes != nil { + e.FieldStart("approvedRoutes") + e.ArrStart() + for _, elem := range s.ApprovedRoutes { + e.Str(elem) + } + e.ArrEnd() + } + } + { + if s.AvailableRoutes != nil { + e.FieldStart("availableRoutes") + e.ArrStart() + for _, elem := range s.AvailableRoutes { + e.Str(elem) + } + e.ArrEnd() + } + } + { + if s.SubnetRoutes != nil { + e.FieldStart("subnetRoutes") + e.ArrStart() + for _, elem := range s.SubnetRoutes { + e.Str(elem) + } + e.ArrEnd() + } + } + { + if s.Tags != nil { + e.FieldStart("tags") + e.ArrStart() + for _, elem := range s.Tags { + e.Str(elem) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfNode = [18]string{ + 0: "id", + 1: "machineKey", + 2: "nodeKey", + 3: "discoKey", + 4: "ipAddresses", + 5: "name", + 6: "user", + 7: "lastSeen", + 8: "expiry", + 9: "preAuthKey", + 10: "createdAt", + 11: "registerMethod", + 12: "givenName", + 13: "online", + 14: "approvedRoutes", + 15: "availableRoutes", + 16: "subnetRoutes", + 17: "tags", +} + +// Decode decodes Node from json. +func (s *Node) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode Node to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "id": + if err := func() error { + s.ID.Reset() + if err := s.ID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"id\"") + } + case "machineKey": + if err := func() error { + s.MachineKey.Reset() + if err := s.MachineKey.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"machineKey\"") + } + case "nodeKey": + if err := func() error { + s.NodeKey.Reset() + if err := s.NodeKey.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"nodeKey\"") + } + case "discoKey": + if err := func() error { + s.DiscoKey.Reset() + if err := s.DiscoKey.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"discoKey\"") + } + case "ipAddresses": + if err := func() error { + s.IpAddresses = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.IpAddresses = append(s.IpAddresses, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ipAddresses\"") + } + case "name": + if err := func() error { + s.Name.Reset() + if err := s.Name.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"name\"") + } + case "user": + if err := func() error { + s.User.Reset() + if err := s.User.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"user\"") + } + case "lastSeen": + if err := func() error { + s.LastSeen.Reset() + if err := s.LastSeen.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"lastSeen\"") + } + case "expiry": + if err := func() error { + s.Expiry.Reset() + if err := s.Expiry.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"expiry\"") + } + case "preAuthKey": + if err := func() error { + s.PreAuthKey.Reset() + if err := s.PreAuthKey.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"preAuthKey\"") + } + case "createdAt": + if err := func() error { + s.CreatedAt.Reset() + if err := s.CreatedAt.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"createdAt\"") + } + case "registerMethod": + if err := func() error { + s.RegisterMethod.Reset() + if err := s.RegisterMethod.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"registerMethod\"") + } + case "givenName": + if err := func() error { + s.GivenName.Reset() + if err := s.GivenName.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"givenName\"") + } + case "online": + if err := func() error { + s.Online.Reset() + if err := s.Online.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"online\"") + } + case "approvedRoutes": + if err := func() error { + s.ApprovedRoutes = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.ApprovedRoutes = append(s.ApprovedRoutes, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"approvedRoutes\"") + } + case "availableRoutes": + if err := func() error { + s.AvailableRoutes = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.AvailableRoutes = append(s.AvailableRoutes, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"availableRoutes\"") + } + case "subnetRoutes": + if err := func() error { + s.SubnetRoutes = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.SubnetRoutes = append(s.SubnetRoutes, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"subnetRoutes\"") + } + case "tags": + if err := func() error { + s.Tags = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.Tags = append(s.Tags, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"tags\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode Node") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *Node) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *Node) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes bool as json. +func (o OptBool) Encode(e *jx.Encoder) { + if !o.Set { + return + } + e.Bool(bool(o.Value)) +} + +// Decode decodes bool from json. +func (o *OptBool) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptBool to nil") + } + o.Set = true + v, err := d.Bool() + if err != nil { + return err + } + o.Value = bool(v) + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptBool) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptBool) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes time.Time as json. +func (o OptDateTime) Encode(e *jx.Encoder, format func(*jx.Encoder, time.Time)) { + if !o.Set { + return + } + format(e, o.Value) +} + +// Decode decodes time.Time from json. +func (o *OptDateTime) Decode(d *jx.Decoder, format func(*jx.Decoder) (time.Time, error)) error { + if o == nil { + return errors.New("invalid: unable to decode OptDateTime to nil") + } + o.Set = true + v, err := format(d) + if err != nil { + return err + } + o.Value = v + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptDateTime) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e, json.EncodeDateTime) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptDateTime) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d, json.DecodeDateTime) +} + +// Encode encodes int32 as json. +func (o OptInt32) Encode(e *jx.Encoder) { + if !o.Set { + return + } + e.Int32(int32(o.Value)) +} + +// Decode decodes int32 from json. +func (o *OptInt32) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptInt32 to nil") + } + o.Set = true + v, err := d.Int32() + if err != nil { + return err + } + o.Value = int32(v) + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptInt32) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptInt32) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes Node as json. +func (o OptNode) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes Node from json. +func (o *OptNode) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptNode to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptNode) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptNode) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes PreAuthKey as json. +func (o OptPreAuthKey) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes PreAuthKey from json. +func (o *OptPreAuthKey) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptPreAuthKey to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptPreAuthKey) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptPreAuthKey) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes RegisterMethod as json. +func (o OptRegisterMethod) Encode(e *jx.Encoder) { + if !o.Set { + return + } + e.Str(string(o.Value)) +} + +// Decode decodes RegisterMethod from json. +func (o *OptRegisterMethod) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptRegisterMethod to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptRegisterMethod) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptRegisterMethod) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes string as json. +func (o OptString) Encode(e *jx.Encoder) { + if !o.Set { + return + } + e.Str(string(o.Value)) +} + +// Decode decodes string from json. +func (o *OptString) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptString to nil") + } + o.Set = true + v, err := d.Str() + if err != nil { + return err + } + o.Value = string(v) + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptString) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptString) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes url.URL as json. +func (o OptURI) Encode(e *jx.Encoder) { + if !o.Set { + return + } + json.EncodeURI(e, o.Value) +} + +// Decode decodes url.URL from json. +func (o *OptURI) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptURI to nil") + } + o.Set = true + v, err := json.DecodeURI(d) + if err != nil { + return err + } + o.Value = v + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptURI) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptURI) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes uint64 as json. +func (o OptUint64) Encode(e *jx.Encoder) { + if !o.Set { + return + } + e.UInt64(uint64(o.Value)) +} + +// Decode decodes uint64 from json. +func (o *OptUint64) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptUint64 to nil") + } + o.Set = true + v, err := d.UInt64() + if err != nil { + return err + } + o.Value = uint64(v) + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptUint64) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptUint64) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes User as json. +func (o OptUser) Encode(e *jx.Encoder) { + if !o.Set { + return + } + o.Value.Encode(e) +} + +// Decode decodes User from json. +func (o *OptUser) Decode(d *jx.Decoder) error { + if o == nil { + return errors.New("invalid: unable to decode OptUser to nil") + } + o.Set = true + if err := o.Value.Decode(d); err != nil { + return err + } + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s OptUser) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *OptUser) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *PreAuthKey) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *PreAuthKey) encodeFields(e *jx.Encoder) { + { + if s.User.Set { + e.FieldStart("user") + s.User.Encode(e) + } + } + { + if s.ID.Set { + e.FieldStart("id") + s.ID.Encode(e) + } + } + { + if s.Key.Set { + e.FieldStart("key") + s.Key.Encode(e) + } + } + { + if s.Reusable.Set { + e.FieldStart("reusable") + s.Reusable.Encode(e) + } + } + { + if s.Ephemeral.Set { + e.FieldStart("ephemeral") + s.Ephemeral.Encode(e) + } + } + { + if s.Used.Set { + e.FieldStart("used") + s.Used.Encode(e) + } + } + { + if s.Expiration.Set { + e.FieldStart("expiration") + s.Expiration.Encode(e, json.EncodeDateTime) + } + } + { + if s.CreatedAt.Set { + e.FieldStart("createdAt") + s.CreatedAt.Encode(e, json.EncodeDateTime) + } + } + { + if s.AclTags != nil { + e.FieldStart("aclTags") + e.ArrStart() + for _, elem := range s.AclTags { + e.Str(elem) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfPreAuthKey = [9]string{ + 0: "user", + 1: "id", + 2: "key", + 3: "reusable", + 4: "ephemeral", + 5: "used", + 6: "expiration", + 7: "createdAt", + 8: "aclTags", +} + +// Decode decodes PreAuthKey from json. +func (s *PreAuthKey) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode PreAuthKey to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "user": + if err := func() error { + s.User.Reset() + if err := s.User.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"user\"") + } + case "id": + if err := func() error { + s.ID.Reset() + if err := s.ID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"id\"") + } + case "key": + if err := func() error { + s.Key.Reset() + if err := s.Key.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"key\"") + } + case "reusable": + if err := func() error { + s.Reusable.Reset() + if err := s.Reusable.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"reusable\"") + } + case "ephemeral": + if err := func() error { + s.Ephemeral.Reset() + if err := s.Ephemeral.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"ephemeral\"") + } + case "used": + if err := func() error { + s.Used.Reset() + if err := s.Used.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"used\"") + } + case "expiration": + if err := func() error { + s.Expiration.Reset() + if err := s.Expiration.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"expiration\"") + } + case "createdAt": + if err := func() error { + s.CreatedAt.Reset() + if err := s.CreatedAt.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"createdAt\"") + } + case "aclTags": + if err := func() error { + s.AclTags = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.AclTags = append(s.AclTags, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"aclTags\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode PreAuthKey") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *PreAuthKey) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *PreAuthKey) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *Problem) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *Problem) encodeFields(e *jx.Encoder) { + { + if s.Type.Set { + e.FieldStart("type") + s.Type.Encode(e) + } + } + { + if s.Title.Set { + e.FieldStart("title") + s.Title.Encode(e) + } + } + { + if s.Status.Set { + e.FieldStart("status") + s.Status.Encode(e) + } + } + { + if s.Detail.Set { + e.FieldStart("detail") + s.Detail.Encode(e) + } + } + { + if s.Instance.Set { + e.FieldStart("instance") + s.Instance.Encode(e) + } + } +} + +var jsonFieldsNameOfProblem = [5]string{ + 0: "type", + 1: "title", + 2: "status", + 3: "detail", + 4: "instance", +} + +// Decode decodes Problem from json. +func (s *Problem) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode Problem to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "type": + if err := func() error { + s.Type.Reset() + if err := s.Type.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"type\"") + } + case "title": + if err := func() error { + s.Title.Reset() + if err := s.Title.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"title\"") + } + case "status": + if err := func() error { + s.Status.Reset() + if err := s.Status.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"status\"") + } + case "detail": + if err := func() error { + s.Detail.Reset() + if err := s.Detail.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"detail\"") + } + case "instance": + if err := func() error { + s.Instance.Reset() + if err := s.Instance.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"instance\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode Problem") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *Problem) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *Problem) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode encodes RegisterMethod as json. +func (s RegisterMethod) Encode(e *jx.Encoder) { + e.Str(string(s)) +} + +// Decode decodes RegisterMethod from json. +func (s *RegisterMethod) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode RegisterMethod to nil") + } + v, err := d.StrBytes() + if err != nil { + return err + } + // Try to use constant string. + switch RegisterMethod(v) { + case RegisterMethodREGISTERMETHODUNSPECIFIED: + *s = RegisterMethodREGISTERMETHODUNSPECIFIED + case RegisterMethodREGISTERMETHODAUTHKEY: + *s = RegisterMethodREGISTERMETHODAUTHKEY + case RegisterMethodREGISTERMETHODCLI: + *s = RegisterMethodREGISTERMETHODCLI + case RegisterMethodREGISTERMETHODOIDC: + *s = RegisterMethodREGISTERMETHODOIDC + default: + *s = RegisterMethod(v) + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s RegisterMethod) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *RegisterMethod) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *RegisterNodeOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *RegisterNodeOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfRegisterNodeOK = [1]string{ + 0: "node", +} + +// Decode decodes RegisterNodeOK from json. +func (s *RegisterNodeOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode RegisterNodeOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode RegisterNodeOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *RegisterNodeOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *RegisterNodeOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *RenameNodeOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *RenameNodeOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfRenameNodeOK = [1]string{ + 0: "node", +} + +// Decode decodes RenameNodeOK from json. +func (s *RenameNodeOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode RenameNodeOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode RenameNodeOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *RenameNodeOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *RenameNodeOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *RenameUserOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *RenameUserOK) encodeFields(e *jx.Encoder) { + { + if s.User.Set { + e.FieldStart("user") + s.User.Encode(e) + } + } +} + +var jsonFieldsNameOfRenameUserOK = [1]string{ + 0: "user", +} + +// Decode decodes RenameUserOK from json. +func (s *RenameUserOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode RenameUserOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "user": + if err := func() error { + s.User.Reset() + if err := s.User.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"user\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode RenameUserOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *RenameUserOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *RenameUserOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *SetApprovedRoutesOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *SetApprovedRoutesOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfSetApprovedRoutesOK = [1]string{ + 0: "node", +} + +// Decode decodes SetApprovedRoutesOK from json. +func (s *SetApprovedRoutesOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode SetApprovedRoutesOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode SetApprovedRoutesOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *SetApprovedRoutesOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *SetApprovedRoutesOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *SetApprovedRoutesReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *SetApprovedRoutesReq) encodeFields(e *jx.Encoder) { + { + if s.Routes != nil { + e.FieldStart("routes") + e.ArrStart() + for _, elem := range s.Routes { + e.Str(elem) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfSetApprovedRoutesReq = [1]string{ + 0: "routes", +} + +// Decode decodes SetApprovedRoutesReq from json. +func (s *SetApprovedRoutesReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode SetApprovedRoutesReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "routes": + if err := func() error { + s.Routes = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.Routes = append(s.Routes, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"routes\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode SetApprovedRoutesReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *SetApprovedRoutesReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *SetApprovedRoutesReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *SetPolicyOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *SetPolicyOK) encodeFields(e *jx.Encoder) { + { + if s.Policy.Set { + e.FieldStart("policy") + s.Policy.Encode(e) + } + } + { + if s.UpdatedAt.Set { + e.FieldStart("updatedAt") + s.UpdatedAt.Encode(e, json.EncodeDateTime) + } + } +} + +var jsonFieldsNameOfSetPolicyOK = [2]string{ + 0: "policy", + 1: "updatedAt", +} + +// Decode decodes SetPolicyOK from json. +func (s *SetPolicyOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode SetPolicyOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "policy": + if err := func() error { + s.Policy.Reset() + if err := s.Policy.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"policy\"") + } + case "updatedAt": + if err := func() error { + s.UpdatedAt.Reset() + if err := s.UpdatedAt.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"updatedAt\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode SetPolicyOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *SetPolicyOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *SetPolicyOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *SetPolicyReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *SetPolicyReq) encodeFields(e *jx.Encoder) { + { + if s.Policy.Set { + e.FieldStart("policy") + s.Policy.Encode(e) + } + } +} + +var jsonFieldsNameOfSetPolicyReq = [1]string{ + 0: "policy", +} + +// Decode decodes SetPolicyReq from json. +func (s *SetPolicyReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode SetPolicyReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "policy": + if err := func() error { + s.Policy.Reset() + if err := s.Policy.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"policy\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode SetPolicyReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *SetPolicyReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *SetPolicyReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *SetTagsOK) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *SetTagsOK) encodeFields(e *jx.Encoder) { + { + if s.Node.Set { + e.FieldStart("node") + s.Node.Encode(e) + } + } +} + +var jsonFieldsNameOfSetTagsOK = [1]string{ + 0: "node", +} + +// Decode decodes SetTagsOK from json. +func (s *SetTagsOK) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode SetTagsOK to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "node": + if err := func() error { + s.Node.Reset() + if err := s.Node.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"node\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode SetTagsOK") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *SetTagsOK) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *SetTagsOK) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *SetTagsReq) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *SetTagsReq) encodeFields(e *jx.Encoder) { + { + if s.Tags != nil { + e.FieldStart("tags") + e.ArrStart() + for _, elem := range s.Tags { + e.Str(elem) + } + e.ArrEnd() + } + } +} + +var jsonFieldsNameOfSetTagsReq = [1]string{ + 0: "tags", +} + +// Decode decodes SetTagsReq from json. +func (s *SetTagsReq) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode SetTagsReq to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "tags": + if err := func() error { + s.Tags = make([]string, 0) + if err := d.Arr(func(d *jx.Decoder) error { + var elem string + v, err := d.Str() + elem = string(v) + if err != nil { + return err + } + s.Tags = append(s.Tags, elem) + return nil + }); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"tags\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode SetTagsReq") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *SetTagsReq) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *SetTagsReq) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} + +// Encode implements json.Marshaler. +func (s *User) Encode(e *jx.Encoder) { + e.ObjStart() + s.encodeFields(e) + e.ObjEnd() +} + +// encodeFields encodes fields. +func (s *User) encodeFields(e *jx.Encoder) { + { + if s.ID.Set { + e.FieldStart("id") + s.ID.Encode(e) + } + } + { + if s.Name.Set { + e.FieldStart("name") + s.Name.Encode(e) + } + } + { + if s.CreatedAt.Set { + e.FieldStart("createdAt") + s.CreatedAt.Encode(e, json.EncodeDateTime) + } + } + { + if s.DisplayName.Set { + e.FieldStart("displayName") + s.DisplayName.Encode(e) + } + } + { + if s.Email.Set { + e.FieldStart("email") + s.Email.Encode(e) + } + } + { + if s.ProviderId.Set { + e.FieldStart("providerId") + s.ProviderId.Encode(e) + } + } + { + if s.Provider.Set { + e.FieldStart("provider") + s.Provider.Encode(e) + } + } + { + if s.ProfilePicUrl.Set { + e.FieldStart("profilePicUrl") + s.ProfilePicUrl.Encode(e) + } + } +} + +var jsonFieldsNameOfUser = [8]string{ + 0: "id", + 1: "name", + 2: "createdAt", + 3: "displayName", + 4: "email", + 5: "providerId", + 6: "provider", + 7: "profilePicUrl", +} + +// Decode decodes User from json. +func (s *User) Decode(d *jx.Decoder) error { + if s == nil { + return errors.New("invalid: unable to decode User to nil") + } + + if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error { + switch string(k) { + case "id": + if err := func() error { + s.ID.Reset() + if err := s.ID.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"id\"") + } + case "name": + if err := func() error { + s.Name.Reset() + if err := s.Name.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"name\"") + } + case "createdAt": + if err := func() error { + s.CreatedAt.Reset() + if err := s.CreatedAt.Decode(d, json.DecodeDateTime); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"createdAt\"") + } + case "displayName": + if err := func() error { + s.DisplayName.Reset() + if err := s.DisplayName.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"displayName\"") + } + case "email": + if err := func() error { + s.Email.Reset() + if err := s.Email.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"email\"") + } + case "providerId": + if err := func() error { + s.ProviderId.Reset() + if err := s.ProviderId.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"providerId\"") + } + case "provider": + if err := func() error { + s.Provider.Reset() + if err := s.Provider.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"provider\"") + } + case "profilePicUrl": + if err := func() error { + s.ProfilePicUrl.Reset() + if err := s.ProfilePicUrl.Decode(d); err != nil { + return err + } + return nil + }(); err != nil { + return errors.Wrap(err, "decode field \"profilePicUrl\"") + } + default: + return d.Skip() + } + return nil + }); err != nil { + return errors.Wrap(err, "decode User") + } + + return nil +} + +// MarshalJSON implements stdjson.Marshaler. +func (s *User) MarshalJSON() ([]byte, error) { + e := jx.Encoder{} + s.Encode(&e) + return e.Bytes(), nil +} + +// UnmarshalJSON implements stdjson.Unmarshaler. +func (s *User) UnmarshalJSON(data []byte) error { + d := jx.DecodeBytes(data) + return s.Decode(d) +} diff --git a/gen/api/v1/oas_labeler_gen.go b/gen/api/v1/oas_labeler_gen.go new file mode 100644 index 00000000..ebad229e --- /dev/null +++ b/gen/api/v1/oas_labeler_gen.go @@ -0,0 +1,42 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "context" + + "go.opentelemetry.io/otel/attribute" +) + +// Labeler is used to allow adding custom attributes to the server request metrics. +type Labeler struct { + attrs []attribute.KeyValue +} + +// Add attributes to the Labeler. +func (l *Labeler) Add(attrs ...attribute.KeyValue) { + l.attrs = append(l.attrs, attrs...) +} + +// AttributeSet returns the attributes added to the Labeler as an attribute.Set. +func (l *Labeler) AttributeSet() attribute.Set { + return attribute.NewSet(l.attrs...) +} + +type labelerContextKey struct{} + +// LabelerFromContext retrieves the Labeler from the provided context, if present. +// +// If no Labeler was found in the provided context a new, empty Labeler is returned and the second +// return value is false. In this case it is safe to use the Labeler but any attributes added to +// it will not be used. +func LabelerFromContext(ctx context.Context) (*Labeler, bool) { + if l, ok := ctx.Value(labelerContextKey{}).(*Labeler); ok { + return l, true + } + return &Labeler{}, false +} + +func contextWithLabeler(ctx context.Context, l *Labeler) context.Context { + return context.WithValue(ctx, labelerContextKey{}, l) +} diff --git a/gen/api/v1/oas_middleware_gen.go b/gen/api/v1/oas_middleware_gen.go new file mode 100644 index 00000000..d08be158 --- /dev/null +++ b/gen/api/v1/oas_middleware_gen.go @@ -0,0 +1,10 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "github.com/ogen-go/ogen/middleware" +) + +// Middleware is middleware type. +type Middleware = middleware.Middleware diff --git a/gen/api/v1/oas_operations_gen.go b/gen/api/v1/oas_operations_gen.go new file mode 100644 index 00000000..7f8369ea --- /dev/null +++ b/gen/api/v1/oas_operations_gen.go @@ -0,0 +1,38 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +// OperationName is the ogen operation name +type OperationName = string + +const ( + AuthApproveOperation OperationName = "AuthApprove" + AuthRegisterOperation OperationName = "AuthRegister" + AuthRejectOperation OperationName = "AuthReject" + BackfillNodeIPsOperation OperationName = "BackfillNodeIPs" + CheckPolicyOperation OperationName = "CheckPolicy" + CreateApiKeyOperation OperationName = "CreateApiKey" + CreatePreAuthKeyOperation OperationName = "CreatePreAuthKey" + CreateUserOperation OperationName = "CreateUser" + DebugCreateNodeOperation OperationName = "DebugCreateNode" + DeleteApiKeyOperation OperationName = "DeleteApiKey" + DeleteNodeOperation OperationName = "DeleteNode" + DeletePreAuthKeyOperation OperationName = "DeletePreAuthKey" + DeleteUserOperation OperationName = "DeleteUser" + ExpireApiKeyOperation OperationName = "ExpireApiKey" + ExpireNodeOperation OperationName = "ExpireNode" + ExpirePreAuthKeyOperation OperationName = "ExpirePreAuthKey" + GetNodeOperation OperationName = "GetNode" + GetPolicyOperation OperationName = "GetPolicy" + HealthOperation OperationName = "Health" + ListApiKeysOperation OperationName = "ListApiKeys" + ListNodesOperation OperationName = "ListNodes" + ListPreAuthKeysOperation OperationName = "ListPreAuthKeys" + ListUsersOperation OperationName = "ListUsers" + RegisterNodeOperation OperationName = "RegisterNode" + RenameNodeOperation OperationName = "RenameNode" + RenameUserOperation OperationName = "RenameUser" + SetApprovedRoutesOperation OperationName = "SetApprovedRoutes" + SetPolicyOperation OperationName = "SetPolicy" + SetTagsOperation OperationName = "SetTags" +) diff --git a/gen/api/v1/oas_parameters_gen.go b/gen/api/v1/oas_parameters_gen.go new file mode 100644 index 00000000..b89733f7 --- /dev/null +++ b/gen/api/v1/oas_parameters_gen.go @@ -0,0 +1,1335 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "net/http" + "net/url" + "time" + + "github.com/go-faster/errors" + "github.com/ogen-go/ogen/conv" + "github.com/ogen-go/ogen/middleware" + "github.com/ogen-go/ogen/ogenerrors" + "github.com/ogen-go/ogen/uri" + "github.com/ogen-go/ogen/validate" +) + +// BackfillNodeIPsParams is parameters of BackfillNodeIPs operation. +type BackfillNodeIPsParams struct { + Confirmed OptBool `json:",omitempty,omitzero"` +} + +func unpackBackfillNodeIPsParams(packed middleware.Parameters) (params BackfillNodeIPsParams) { + { + key := middleware.ParameterKey{ + Name: "confirmed", + In: "query", + } + if v, ok := packed[key]; ok { + params.Confirmed = v.(OptBool) + } + } + return params +} + +func decodeBackfillNodeIPsParams(args [0]string, argsEscaped bool, r *http.Request) (params BackfillNodeIPsParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode query: confirmed. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "confirmed", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotConfirmedVal bool + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToBool(val) + if err != nil { + return err + } + + paramsDotConfirmedVal = c + return nil + }(); err != nil { + return err + } + params.Confirmed.SetTo(paramsDotConfirmedVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "confirmed", + In: "query", + Err: err, + } + } + return params, nil +} + +// DeleteApiKeyParams is parameters of DeleteApiKey operation. +type DeleteApiKeyParams struct { + Prefix string + ID OptUint64 `json:",omitempty,omitzero"` +} + +func unpackDeleteApiKeyParams(packed middleware.Parameters) (params DeleteApiKeyParams) { + { + key := middleware.ParameterKey{ + Name: "prefix", + In: "path", + } + params.Prefix = packed[key].(string) + } + { + key := middleware.ParameterKey{ + Name: "id", + In: "query", + } + if v, ok := packed[key]; ok { + params.ID = v.(OptUint64) + } + } + return params +} + +func decodeDeleteApiKeyParams(args [1]string, argsEscaped bool, r *http.Request) (params DeleteApiKeyParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode path: prefix. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "prefix", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + params.Prefix = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "prefix", + In: "path", + Err: err, + } + } + // Decode query: id. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "id", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotIDVal uint64 + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + paramsDotIDVal = c + return nil + }(); err != nil { + return err + } + params.ID.SetTo(paramsDotIDVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "id", + In: "query", + Err: err, + } + } + return params, nil +} + +// DeleteNodeParams is parameters of DeleteNode operation. +type DeleteNodeParams struct { + NodeID uint64 +} + +func unpackDeleteNodeParams(packed middleware.Parameters) (params DeleteNodeParams) { + { + key := middleware.ParameterKey{ + Name: "node_id", + In: "path", + } + params.NodeID = packed[key].(uint64) + } + return params +} + +func decodeDeleteNodeParams(args [1]string, argsEscaped bool, r *http.Request) (params DeleteNodeParams, _ error) { + // Decode path: node_id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "node_id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.NodeID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "node_id", + In: "path", + Err: err, + } + } + return params, nil +} + +// DeletePreAuthKeyParams is parameters of DeletePreAuthKey operation. +type DeletePreAuthKeyParams struct { + ID OptUint64 `json:",omitempty,omitzero"` +} + +func unpackDeletePreAuthKeyParams(packed middleware.Parameters) (params DeletePreAuthKeyParams) { + { + key := middleware.ParameterKey{ + Name: "id", + In: "query", + } + if v, ok := packed[key]; ok { + params.ID = v.(OptUint64) + } + } + return params +} + +func decodeDeletePreAuthKeyParams(args [0]string, argsEscaped bool, r *http.Request) (params DeletePreAuthKeyParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode query: id. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "id", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotIDVal uint64 + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + paramsDotIDVal = c + return nil + }(); err != nil { + return err + } + params.ID.SetTo(paramsDotIDVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "id", + In: "query", + Err: err, + } + } + return params, nil +} + +// DeleteUserParams is parameters of DeleteUser operation. +type DeleteUserParams struct { + ID uint64 +} + +func unpackDeleteUserParams(packed middleware.Parameters) (params DeleteUserParams) { + { + key := middleware.ParameterKey{ + Name: "id", + In: "path", + } + params.ID = packed[key].(uint64) + } + return params +} + +func decodeDeleteUserParams(args [1]string, argsEscaped bool, r *http.Request) (params DeleteUserParams, _ error) { + // Decode path: id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.ID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "id", + In: "path", + Err: err, + } + } + return params, nil +} + +// ExpireNodeParams is parameters of ExpireNode operation. +type ExpireNodeParams struct { + NodeID uint64 + Expiry OptDateTime `json:",omitempty,omitzero"` + DisableExpiry OptBool `json:",omitempty,omitzero"` +} + +func unpackExpireNodeParams(packed middleware.Parameters) (params ExpireNodeParams) { + { + key := middleware.ParameterKey{ + Name: "node_id", + In: "path", + } + params.NodeID = packed[key].(uint64) + } + { + key := middleware.ParameterKey{ + Name: "expiry", + In: "query", + } + if v, ok := packed[key]; ok { + params.Expiry = v.(OptDateTime) + } + } + { + key := middleware.ParameterKey{ + Name: "disable_expiry", + In: "query", + } + if v, ok := packed[key]; ok { + params.DisableExpiry = v.(OptBool) + } + } + return params +} + +func decodeExpireNodeParams(args [1]string, argsEscaped bool, r *http.Request) (params ExpireNodeParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode path: node_id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "node_id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.NodeID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "node_id", + In: "path", + Err: err, + } + } + // Decode query: expiry. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "expiry", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotExpiryVal time.Time + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToDateTime(val) + if err != nil { + return err + } + + paramsDotExpiryVal = c + return nil + }(); err != nil { + return err + } + params.Expiry.SetTo(paramsDotExpiryVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "expiry", + In: "query", + Err: err, + } + } + // Decode query: disable_expiry. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "disable_expiry", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotDisableExpiryVal bool + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToBool(val) + if err != nil { + return err + } + + paramsDotDisableExpiryVal = c + return nil + }(); err != nil { + return err + } + params.DisableExpiry.SetTo(paramsDotDisableExpiryVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "disable_expiry", + In: "query", + Err: err, + } + } + return params, nil +} + +// GetNodeParams is parameters of GetNode operation. +type GetNodeParams struct { + NodeID uint64 +} + +func unpackGetNodeParams(packed middleware.Parameters) (params GetNodeParams) { + { + key := middleware.ParameterKey{ + Name: "node_id", + In: "path", + } + params.NodeID = packed[key].(uint64) + } + return params +} + +func decodeGetNodeParams(args [1]string, argsEscaped bool, r *http.Request) (params GetNodeParams, _ error) { + // Decode path: node_id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "node_id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.NodeID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "node_id", + In: "path", + Err: err, + } + } + return params, nil +} + +// ListNodesParams is parameters of ListNodes operation. +type ListNodesParams struct { + User OptString `json:",omitempty,omitzero"` +} + +func unpackListNodesParams(packed middleware.Parameters) (params ListNodesParams) { + { + key := middleware.ParameterKey{ + Name: "user", + In: "query", + } + if v, ok := packed[key]; ok { + params.User = v.(OptString) + } + } + return params +} + +func decodeListNodesParams(args [0]string, argsEscaped bool, r *http.Request) (params ListNodesParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode query: user. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "user", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotUserVal string + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + paramsDotUserVal = c + return nil + }(); err != nil { + return err + } + params.User.SetTo(paramsDotUserVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "user", + In: "query", + Err: err, + } + } + return params, nil +} + +// ListUsersParams is parameters of ListUsers operation. +type ListUsersParams struct { + ID OptUint64 `json:",omitempty,omitzero"` + Name OptString `json:",omitempty,omitzero"` + Email OptString `json:",omitempty,omitzero"` +} + +func unpackListUsersParams(packed middleware.Parameters) (params ListUsersParams) { + { + key := middleware.ParameterKey{ + Name: "id", + In: "query", + } + if v, ok := packed[key]; ok { + params.ID = v.(OptUint64) + } + } + { + key := middleware.ParameterKey{ + Name: "name", + In: "query", + } + if v, ok := packed[key]; ok { + params.Name = v.(OptString) + } + } + { + key := middleware.ParameterKey{ + Name: "email", + In: "query", + } + if v, ok := packed[key]; ok { + params.Email = v.(OptString) + } + } + return params +} + +func decodeListUsersParams(args [0]string, argsEscaped bool, r *http.Request) (params ListUsersParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode query: id. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "id", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotIDVal uint64 + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + paramsDotIDVal = c + return nil + }(); err != nil { + return err + } + params.ID.SetTo(paramsDotIDVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "id", + In: "query", + Err: err, + } + } + // Decode query: name. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "name", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotNameVal string + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + paramsDotNameVal = c + return nil + }(); err != nil { + return err + } + params.Name.SetTo(paramsDotNameVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "name", + In: "query", + Err: err, + } + } + // Decode query: email. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "email", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotEmailVal string + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + paramsDotEmailVal = c + return nil + }(); err != nil { + return err + } + params.Email.SetTo(paramsDotEmailVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "email", + In: "query", + Err: err, + } + } + return params, nil +} + +// RegisterNodeParams is parameters of RegisterNode operation. +type RegisterNodeParams struct { + User OptString `json:",omitempty,omitzero"` + Key OptString `json:",omitempty,omitzero"` +} + +func unpackRegisterNodeParams(packed middleware.Parameters) (params RegisterNodeParams) { + { + key := middleware.ParameterKey{ + Name: "user", + In: "query", + } + if v, ok := packed[key]; ok { + params.User = v.(OptString) + } + } + { + key := middleware.ParameterKey{ + Name: "key", + In: "query", + } + if v, ok := packed[key]; ok { + params.Key = v.(OptString) + } + } + return params +} + +func decodeRegisterNodeParams(args [0]string, argsEscaped bool, r *http.Request) (params RegisterNodeParams, _ error) { + q := uri.NewQueryDecoder(r.URL.Query()) + // Decode query: user. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "user", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotUserVal string + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + paramsDotUserVal = c + return nil + }(); err != nil { + return err + } + params.User.SetTo(paramsDotUserVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "user", + In: "query", + Err: err, + } + } + // Decode query: key. + if err := func() error { + cfg := uri.QueryParameterDecodingConfig{ + Name: "key", + Style: uri.QueryStyleForm, + Explode: true, + } + + if err := q.HasParam(cfg); err == nil { + if err := q.DecodeParam(cfg, func(d uri.Decoder) error { + var paramsDotKeyVal string + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + paramsDotKeyVal = c + return nil + }(); err != nil { + return err + } + params.Key.SetTo(paramsDotKeyVal) + return nil + }); err != nil { + return err + } + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "key", + In: "query", + Err: err, + } + } + return params, nil +} + +// RenameNodeParams is parameters of RenameNode operation. +type RenameNodeParams struct { + NodeID uint64 + NewName string +} + +func unpackRenameNodeParams(packed middleware.Parameters) (params RenameNodeParams) { + { + key := middleware.ParameterKey{ + Name: "node_id", + In: "path", + } + params.NodeID = packed[key].(uint64) + } + { + key := middleware.ParameterKey{ + Name: "new_name", + In: "path", + } + params.NewName = packed[key].(string) + } + return params +} + +func decodeRenameNodeParams(args [2]string, argsEscaped bool, r *http.Request) (params RenameNodeParams, _ error) { + // Decode path: node_id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "node_id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.NodeID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "node_id", + In: "path", + Err: err, + } + } + // Decode path: new_name. + if err := func() error { + param := args[1] + if argsEscaped { + unescaped, err := url.PathUnescape(args[1]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "new_name", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + params.NewName = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "new_name", + In: "path", + Err: err, + } + } + return params, nil +} + +// RenameUserParams is parameters of RenameUser operation. +type RenameUserParams struct { + OldID uint64 + NewName string +} + +func unpackRenameUserParams(packed middleware.Parameters) (params RenameUserParams) { + { + key := middleware.ParameterKey{ + Name: "old_id", + In: "path", + } + params.OldID = packed[key].(uint64) + } + { + key := middleware.ParameterKey{ + Name: "new_name", + In: "path", + } + params.NewName = packed[key].(string) + } + return params +} + +func decodeRenameUserParams(args [2]string, argsEscaped bool, r *http.Request) (params RenameUserParams, _ error) { + // Decode path: old_id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "old_id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.OldID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "old_id", + In: "path", + Err: err, + } + } + // Decode path: new_name. + if err := func() error { + param := args[1] + if argsEscaped { + unescaped, err := url.PathUnescape(args[1]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "new_name", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToString(val) + if err != nil { + return err + } + + params.NewName = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "new_name", + In: "path", + Err: err, + } + } + return params, nil +} + +// SetApprovedRoutesParams is parameters of SetApprovedRoutes operation. +type SetApprovedRoutesParams struct { + NodeID uint64 +} + +func unpackSetApprovedRoutesParams(packed middleware.Parameters) (params SetApprovedRoutesParams) { + { + key := middleware.ParameterKey{ + Name: "node_id", + In: "path", + } + params.NodeID = packed[key].(uint64) + } + return params +} + +func decodeSetApprovedRoutesParams(args [1]string, argsEscaped bool, r *http.Request) (params SetApprovedRoutesParams, _ error) { + // Decode path: node_id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "node_id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.NodeID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "node_id", + In: "path", + Err: err, + } + } + return params, nil +} + +// SetTagsParams is parameters of SetTags operation. +type SetTagsParams struct { + NodeID uint64 +} + +func unpackSetTagsParams(packed middleware.Parameters) (params SetTagsParams) { + { + key := middleware.ParameterKey{ + Name: "node_id", + In: "path", + } + params.NodeID = packed[key].(uint64) + } + return params +} + +func decodeSetTagsParams(args [1]string, argsEscaped bool, r *http.Request) (params SetTagsParams, _ error) { + // Decode path: node_id. + if err := func() error { + param := args[0] + if argsEscaped { + unescaped, err := url.PathUnescape(args[0]) + if err != nil { + return errors.Wrap(err, "unescape path") + } + param = unescaped + } + if len(param) > 0 { + d := uri.NewPathDecoder(uri.PathDecoderConfig{ + Param: "node_id", + Value: param, + Style: uri.PathStyleSimple, + Explode: false, + }) + + if err := func() error { + val, err := d.DecodeValue() + if err != nil { + return err + } + + c, err := conv.ToUint64(val) + if err != nil { + return err + } + + params.NodeID = c + return nil + }(); err != nil { + return err + } + } else { + return validate.ErrFieldRequired + } + return nil + }(); err != nil { + return params, &ogenerrors.DecodeParamError{ + Name: "node_id", + In: "path", + Err: err, + } + } + return params, nil +} diff --git a/gen/api/v1/oas_request_decoders_gen.go b/gen/api/v1/oas_request_decoders_gen.go new file mode 100644 index 00000000..a3e74848 --- /dev/null +++ b/gen/api/v1/oas_request_decoders_gen.go @@ -0,0 +1,938 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "bytes" + "io" + "mime" + "net/http" + + "github.com/go-faster/errors" + "github.com/go-faster/jx" + "github.com/ogen-go/ogen/ogenerrors" + "github.com/ogen-go/ogen/validate" +) + +func (s *Server) decodeAuthApproveRequest(r *http.Request) ( + req *AuthApproveReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request AuthApproveReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeAuthRegisterRequest(r *http.Request) ( + req *AuthRegisterReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request AuthRegisterReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeAuthRejectRequest(r *http.Request) ( + req *AuthRejectReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request AuthRejectReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeCheckPolicyRequest(r *http.Request) ( + req *CheckPolicyReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request CheckPolicyReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeCreateApiKeyRequest(r *http.Request) ( + req *CreateApiKeyReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request CreateApiKeyReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeCreatePreAuthKeyRequest(r *http.Request) ( + req *CreatePreAuthKeyReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request CreatePreAuthKeyReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeCreateUserRequest(r *http.Request) ( + req *CreateUserReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request CreateUserReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeDebugCreateNodeRequest(r *http.Request) ( + req *DebugCreateNodeReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request DebugCreateNodeReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeExpireApiKeyRequest(r *http.Request) ( + req *ExpireApiKeyReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request ExpireApiKeyReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeExpirePreAuthKeyRequest(r *http.Request) ( + req *ExpirePreAuthKeyReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request ExpirePreAuthKeyReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeSetApprovedRoutesRequest(r *http.Request) ( + req *SetApprovedRoutesReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request SetApprovedRoutesReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeSetPolicyRequest(r *http.Request) ( + req *SetPolicyReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request SetPolicyReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} + +func (s *Server) decodeSetTagsRequest(r *http.Request) ( + req *SetTagsReq, + rawBody []byte, + close func() error, + rerr error, +) { + var closers []func() error + close = func() error { + var merr error + // Close in reverse order, to match defer behavior. + for i := len(closers) - 1; i >= 0; i-- { + c := closers[i] + merr = errors.Join(merr, c()) + } + return merr + } + defer func() { + if rerr != nil { + rerr = errors.Join(rerr, close()) + } + }() + ct, _, err := mime.ParseMediaType(r.Header.Get("Content-Type")) + if err != nil { + return req, rawBody, close, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + if r.ContentLength == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + buf, err := io.ReadAll(r.Body) + defer func() { + _ = r.Body.Close() + }() + if err != nil { + return req, rawBody, close, err + } + + // Reset the body to allow for downstream reading. + r.Body = io.NopCloser(bytes.NewBuffer(buf)) + + if len(buf) == 0 { + return req, rawBody, close, validate.ErrBodyRequired + } + + rawBody = append(rawBody, buf...) + d := jx.DecodeBytes(buf) + + var request SetTagsReq + if err := func() error { + if err := request.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return req, rawBody, close, err + } + return &request, rawBody, close, nil + default: + return req, rawBody, close, validate.InvalidContentType(ct) + } +} diff --git a/gen/api/v1/oas_request_encoders_gen.go b/gen/api/v1/oas_request_encoders_gen.go new file mode 100644 index 00000000..182e12de --- /dev/null +++ b/gen/api/v1/oas_request_encoders_gen.go @@ -0,0 +1,193 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "bytes" + "net/http" + + "github.com/go-faster/jx" + ht "github.com/ogen-go/ogen/http" +) + +func encodeAuthApproveRequest( + req *AuthApproveReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeAuthRegisterRequest( + req *AuthRegisterReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeAuthRejectRequest( + req *AuthRejectReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeCheckPolicyRequest( + req *CheckPolicyReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeCreateApiKeyRequest( + req *CreateApiKeyReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeCreatePreAuthKeyRequest( + req *CreatePreAuthKeyReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeCreateUserRequest( + req *CreateUserReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeDebugCreateNodeRequest( + req *DebugCreateNodeReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeExpireApiKeyRequest( + req *ExpireApiKeyReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeExpirePreAuthKeyRequest( + req *ExpirePreAuthKeyReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeSetApprovedRoutesRequest( + req *SetApprovedRoutesReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeSetPolicyRequest( + req *SetPolicyReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} + +func encodeSetTagsRequest( + req *SetTagsReq, + r *http.Request, +) error { + const contentType = "application/json" + e := new(jx.Encoder) + { + req.Encode(e) + } + encoded := e.Bytes() + ht.SetBody(r, bytes.NewReader(encoded), contentType) + return nil +} diff --git a/gen/api/v1/oas_response_decoders_gen.go b/gen/api/v1/oas_response_decoders_gen.go new file mode 100644 index 00000000..961de7e0 --- /dev/null +++ b/gen/api/v1/oas_response_decoders_gen.go @@ -0,0 +1,2502 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "io" + "mime" + "net/http" + + "github.com/go-faster/errors" + "github.com/go-faster/jx" + "github.com/ogen-go/ogen/ogenerrors" + "github.com/ogen-go/ogen/validate" +) + +func decodeAuthApproveResponse(resp *http.Response) (res *AuthApproveOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response AuthApproveOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeAuthRegisterResponse(resp *http.Response) (res *AuthRegisterOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response AuthRegisterOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeAuthRejectResponse(resp *http.Response) (res *AuthRejectOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response AuthRejectOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeBackfillNodeIPsResponse(resp *http.Response) (res *BackfillNodeIPsOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response BackfillNodeIPsOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeCheckPolicyResponse(resp *http.Response) (res *CheckPolicyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response CheckPolicyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeCreateApiKeyResponse(resp *http.Response) (res *CreateApiKeyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response CreateApiKeyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeCreatePreAuthKeyResponse(resp *http.Response) (res *CreatePreAuthKeyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response CreatePreAuthKeyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeCreateUserResponse(resp *http.Response) (res *CreateUserOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response CreateUserOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeDebugCreateNodeResponse(resp *http.Response) (res *DebugCreateNodeOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response DebugCreateNodeOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeDeleteApiKeyResponse(resp *http.Response) (res *DeleteApiKeyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response DeleteApiKeyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeDeleteNodeResponse(resp *http.Response) (res *DeleteNodeOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response DeleteNodeOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeDeletePreAuthKeyResponse(resp *http.Response) (res *DeletePreAuthKeyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response DeletePreAuthKeyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeDeleteUserResponse(resp *http.Response) (res *DeleteUserOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response DeleteUserOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeExpireApiKeyResponse(resp *http.Response) (res *ExpireApiKeyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ExpireApiKeyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeExpireNodeResponse(resp *http.Response) (res *ExpireNodeOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ExpireNodeOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeExpirePreAuthKeyResponse(resp *http.Response) (res *ExpirePreAuthKeyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ExpirePreAuthKeyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeGetNodeResponse(resp *http.Response) (res *GetNodeOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response GetNodeOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeGetPolicyResponse(resp *http.Response) (res *GetPolicyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response GetPolicyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeHealthResponse(resp *http.Response) (res *HealthOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response HealthOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeListApiKeysResponse(resp *http.Response) (res *ListApiKeysOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ListApiKeysOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeListNodesResponse(resp *http.Response) (res *ListNodesOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ListNodesOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeListPreAuthKeysResponse(resp *http.Response) (res *ListPreAuthKeysOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ListPreAuthKeysOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeListUsersResponse(resp *http.Response) (res *ListUsersOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response ListUsersOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeRegisterNodeResponse(resp *http.Response) (res *RegisterNodeOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response RegisterNodeOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeRenameNodeResponse(resp *http.Response) (res *RenameNodeOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response RenameNodeOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeRenameUserResponse(resp *http.Response) (res *RenameUserOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response RenameUserOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeSetApprovedRoutesResponse(resp *http.Response) (res *SetApprovedRoutesOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response SetApprovedRoutesOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeSetPolicyResponse(resp *http.Response) (res *SetPolicyOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response SetPolicyOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} + +func decodeSetTagsResponse(resp *http.Response) (res *SetTagsOK, _ error) { + switch resp.StatusCode { + case 200: + // Code 200. + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response SetTagsOK + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + // Validate response. + if err := func() error { + if err := response.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return res, errors.Wrap(err, "validate") + } + return &response, nil + default: + return res, validate.InvalidContentType(ct) + } + } + // Convenient error response. + defRes, err := func() (res *ErrorStatusCode, err error) { + ct, _, err := mime.ParseMediaType(resp.Header.Get("Content-Type")) + if err != nil { + return res, errors.Wrap(err, "parse media type") + } + switch { + case ct == "application/problem+json": + buf, err := io.ReadAll(resp.Body) + if err != nil { + return res, err + } + d := jx.DecodeBytes(buf) + + var response Problem + if err := func() error { + if err := response.Decode(d); err != nil { + return err + } + if err := d.Skip(); err != io.EOF { + return errors.New("unexpected trailing data") + } + return nil + }(); err != nil { + err = &ogenerrors.DecodeBodyError{ + ContentType: ct, + Body: buf, + Err: err, + } + return res, err + } + return &ErrorStatusCode{ + StatusCode: resp.StatusCode, + Response: response, + }, nil + default: + return res, validate.InvalidContentType(ct) + } + }() + if err != nil { + return res, errors.Wrapf(err, "default (code %d)", resp.StatusCode) + } + return res, errors.Wrap(defRes, "error") +} diff --git a/gen/api/v1/oas_response_encoders_gen.go b/gen/api/v1/oas_response_encoders_gen.go new file mode 100644 index 00000000..ffd650e6 --- /dev/null +++ b/gen/api/v1/oas_response_encoders_gen.go @@ -0,0 +1,415 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "net/http" + + "github.com/go-faster/errors" + "github.com/go-faster/jx" + ht "github.com/ogen-go/ogen/http" + "go.opentelemetry.io/otel/codes" + "go.opentelemetry.io/otel/trace" +) + +func encodeAuthApproveResponse(response *AuthApproveOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeAuthRegisterResponse(response *AuthRegisterOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeAuthRejectResponse(response *AuthRejectOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeBackfillNodeIPsResponse(response *BackfillNodeIPsOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeCheckPolicyResponse(response *CheckPolicyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeCreateApiKeyResponse(response *CreateApiKeyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeCreatePreAuthKeyResponse(response *CreatePreAuthKeyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeCreateUserResponse(response *CreateUserOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeDebugCreateNodeResponse(response *DebugCreateNodeOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeDeleteApiKeyResponse(response *DeleteApiKeyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeDeleteNodeResponse(response *DeleteNodeOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeDeletePreAuthKeyResponse(response *DeletePreAuthKeyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeDeleteUserResponse(response *DeleteUserOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeExpireApiKeyResponse(response *ExpireApiKeyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeExpireNodeResponse(response *ExpireNodeOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeExpirePreAuthKeyResponse(response *ExpirePreAuthKeyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeGetNodeResponse(response *GetNodeOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeGetPolicyResponse(response *GetPolicyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeHealthResponse(response *HealthOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeListApiKeysResponse(response *ListApiKeysOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeListNodesResponse(response *ListNodesOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeListPreAuthKeysResponse(response *ListPreAuthKeysOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeListUsersResponse(response *ListUsersOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeRegisterNodeResponse(response *RegisterNodeOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeRenameNodeResponse(response *RenameNodeOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeRenameUserResponse(response *RenameUserOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeSetApprovedRoutesResponse(response *SetApprovedRoutesOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeSetPolicyResponse(response *SetPolicyOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeSetTagsResponse(response *SetTagsOK, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/json; charset=utf-8") + w.WriteHeader(200) + + e := new(jx.Encoder) + response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + return nil +} + +func encodeErrorResponse(response *ErrorStatusCode, w http.ResponseWriter, span trace.Span) error { + w.Header().Set("Content-Type", "application/problem+json") + code := response.StatusCode + if code == 0 { + // Set default status code. + code = http.StatusOK + } + w.WriteHeader(code) + if code >= http.StatusInternalServerError { + span.SetStatus(codes.Error, http.StatusText(code)) + } + + e := new(jx.Encoder) + response.Response.Encode(e) + if _, err := e.WriteTo(w); err != nil { + return errors.Wrap(err, "write") + } + + if code >= http.StatusInternalServerError { + return errors.Wrapf(ht.ErrInternalServerErrorResponse, "code: %d, message: %s", code, http.StatusText(code)) + } + return nil + +} diff --git a/gen/api/v1/oas_router_gen.go b/gen/api/v1/oas_router_gen.go new file mode 100644 index 00000000..4c4bd7bc --- /dev/null +++ b/gen/api/v1/oas_router_gen.go @@ -0,0 +1,1753 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "net/http" + "net/url" + "strings" + + "github.com/ogen-go/ogen/uri" +) + +var ( + rn10AllowedHeaders = map[string]string{ + "GET": "Authorization", + "POST": "Authorization,Content-Type", + } + rn21AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn16AllowedHeaders = map[string]string{ + "DELETE": "Authorization", + } + rn1AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn3AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn5AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn14AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn25AllowedHeaders = map[string]string{ + "GET": "Authorization", + } + rn26AllowedHeaders = map[string]string{ + "GET": "Authorization", + } + rn7AllowedHeaders = map[string]string{ + "POST": "Authorization", + } + rn27AllowedHeaders = map[string]string{ + "POST": "Authorization", + } + rn18AllowedHeaders = map[string]string{ + "DELETE": "Authorization", + "GET": "Authorization", + } + rn33AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn22AllowedHeaders = map[string]string{ + "POST": "Authorization", + } + rn30AllowedHeaders = map[string]string{ + "POST": "Authorization", + } + rn34AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn24AllowedHeaders = map[string]string{ + "GET": "Authorization", + "PUT": "Authorization,Content-Type", + } + rn8AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn12AllowedHeaders = map[string]string{ + "DELETE": "Authorization", + "GET": "Authorization", + "POST": "Authorization,Content-Type", + } + rn23AllowedHeaders = map[string]string{ + "POST": "Authorization,Content-Type", + } + rn13AllowedHeaders = map[string]string{ + "GET": "Authorization", + "POST": "Authorization,Content-Type", + } + rn20AllowedHeaders = map[string]string{ + "DELETE": "Authorization", + } + rn32AllowedHeaders = map[string]string{ + "POST": "Authorization", + } +) + +func (s *Server) cutPrefix(path string) (string, bool) { + prefix := s.cfg.Prefix + if prefix == "" { + return path, true + } + if !strings.HasPrefix(path, prefix) { + // Prefix doesn't match. + return "", false + } + // Cut prefix from the path. + return strings.TrimPrefix(path, prefix), true +} + +// ServeHTTP serves http request as defined by OpenAPI v3 specification, +// calling handler that matches the path or returning not found error. +func (s *Server) ServeHTTP(w http.ResponseWriter, r *http.Request) { + elem := r.URL.Path + elemIsEscaped := false + if rawPath := r.URL.RawPath; rawPath != "" { + if normalized, ok := uri.NormalizeEscapedPath(rawPath); ok { + elem = normalized + elemIsEscaped = strings.ContainsRune(elem, '%') + } + } + + elem, ok := s.cutPrefix(elem) + if !ok || len(elem) == 0 { + s.notFound(w, r) + return + } + args := [2]string{} + + // Static code generated router with unwrapped path search. + switch { + default: + if len(elem) == 0 { + break + } + switch elem[0] { + case '/': // Prefix: "/api/v1/" + + if l := len("/api/v1/"); len(elem) >= l && elem[0:l] == "/api/v1/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'a': // Prefix: "a" + + if l := len("a"); len(elem) >= l && elem[0:l] == "a" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'p': // Prefix: "pikey" + + if l := len("pikey"); len(elem) >= l && elem[0:l] == "pikey" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch r.Method { + case "GET": + s.handleListApiKeysRequest([0]string{}, elemIsEscaped, w, r) + case "POST": + s.handleCreateApiKeyRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "GET,POST", + allowedHeaders: rn10AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'e': // Prefix: "expire" + origElem := elem + if l := len("expire"); len(elem) >= l && elem[0:l] == "expire" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleExpireApiKeyRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn21AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + elem = origElem + } + // Param: "prefix" + // Leaf parameter, slashes are prohibited + idx := strings.IndexByte(elem, '/') + if idx >= 0 { + break + } + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "DELETE": + s.handleDeleteApiKeyRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "DELETE", + allowedHeaders: rn16AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + + } + + case 'u': // Prefix: "uth/" + + if l := len("uth/"); len(elem) >= l && elem[0:l] == "uth/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'a': // Prefix: "approve" + + if l := len("approve"); len(elem) >= l && elem[0:l] == "approve" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleAuthApproveRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn1AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + case 'r': // Prefix: "re" + + if l := len("re"); len(elem) >= l && elem[0:l] == "re" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'g': // Prefix: "gister" + + if l := len("gister"); len(elem) >= l && elem[0:l] == "gister" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleAuthRegisterRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn3AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + case 'j': // Prefix: "ject" + + if l := len("ject"); len(elem) >= l && elem[0:l] == "ject" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleAuthRejectRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn5AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + } + + } + + } + + case 'd': // Prefix: "debug/node" + + if l := len("debug/node"); len(elem) >= l && elem[0:l] == "debug/node" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleDebugCreateNodeRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn14AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + case 'h': // Prefix: "health" + + if l := len("health"); len(elem) >= l && elem[0:l] == "health" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "GET": + s.handleHealthRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "GET", + allowedHeaders: rn25AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + + case 'n': // Prefix: "node" + + if l := len("node"); len(elem) >= l && elem[0:l] == "node" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch r.Method { + case "GET": + s.handleListNodesRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "GET", + allowedHeaders: rn26AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'b': // Prefix: "backfillips" + origElem := elem + if l := len("backfillips"); len(elem) >= l && elem[0:l] == "backfillips" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleBackfillNodeIPsRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn7AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + + elem = origElem + case 'r': // Prefix: "register" + origElem := elem + if l := len("register"); len(elem) >= l && elem[0:l] == "register" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleRegisterNodeRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn27AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + + elem = origElem + } + // Param: "node_id" + // Match until "/" + idx := strings.IndexByte(elem, '/') + if idx < 0 { + idx = len(elem) + } + args[0] = elem[:idx] + elem = elem[idx:] + + if len(elem) == 0 { + switch r.Method { + case "DELETE": + s.handleDeleteNodeRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + case "GET": + s.handleGetNodeRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "DELETE,GET", + allowedHeaders: rn18AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'a': // Prefix: "approve_routes" + + if l := len("approve_routes"); len(elem) >= l && elem[0:l] == "approve_routes" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleSetApprovedRoutesRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn33AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + case 'e': // Prefix: "expire" + + if l := len("expire"); len(elem) >= l && elem[0:l] == "expire" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleExpireNodeRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn22AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + + case 'r': // Prefix: "rename/" + + if l := len("rename/"); len(elem) >= l && elem[0:l] == "rename/" { + elem = elem[l:] + } else { + break + } + + // Param: "new_name" + // Leaf parameter, slashes are prohibited + idx := strings.IndexByte(elem, '/') + if idx >= 0 { + break + } + args[1] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleRenameNodeRequest([2]string{ + args[0], + args[1], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn30AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + + case 't': // Prefix: "tags" + + if l := len("tags"); len(elem) >= l && elem[0:l] == "tags" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleSetTagsRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn34AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + } + + } + + } + + case 'p': // Prefix: "p" + + if l := len("p"); len(elem) >= l && elem[0:l] == "p" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'o': // Prefix: "olicy" + + if l := len("olicy"); len(elem) >= l && elem[0:l] == "olicy" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch r.Method { + case "GET": + s.handleGetPolicyRequest([0]string{}, elemIsEscaped, w, r) + case "PUT": + s.handleSetPolicyRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "GET,PUT", + allowedHeaders: rn24AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + switch elem[0] { + case '/': // Prefix: "/check" + + if l := len("/check"); len(elem) >= l && elem[0:l] == "/check" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleCheckPolicyRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn8AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + } + + case 'r': // Prefix: "reauthkey" + + if l := len("reauthkey"); len(elem) >= l && elem[0:l] == "reauthkey" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch r.Method { + case "DELETE": + s.handleDeletePreAuthKeyRequest([0]string{}, elemIsEscaped, w, r) + case "GET": + s.handleListPreAuthKeysRequest([0]string{}, elemIsEscaped, w, r) + case "POST": + s.handleCreatePreAuthKeyRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "DELETE,GET,POST", + allowedHeaders: rn12AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + switch elem[0] { + case '/': // Prefix: "/expire" + + if l := len("/expire"); len(elem) >= l && elem[0:l] == "/expire" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleExpirePreAuthKeyRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn23AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + + } + + } + + case 'u': // Prefix: "user" + + if l := len("user"); len(elem) >= l && elem[0:l] == "user" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch r.Method { + case "GET": + s.handleListUsersRequest([0]string{}, elemIsEscaped, w, r) + case "POST": + s.handleCreateUserRequest([0]string{}, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "GET,POST", + allowedHeaders: rn13AllowedHeaders, + acceptPost: "application/json", + acceptPatch: "", + }) + } + + return + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + // Param: "id" + // Match until "/" + idx := strings.IndexByte(elem, '/') + if idx < 0 { + idx = len(elem) + } + args[0] = elem[:idx] + elem = elem[idx:] + + if len(elem) == 0 { + switch r.Method { + case "DELETE": + s.handleDeleteUserRequest([1]string{ + args[0], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "DELETE", + allowedHeaders: rn20AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + switch elem[0] { + case '/': // Prefix: "/rename/" + + if l := len("/rename/"); len(elem) >= l && elem[0:l] == "/rename/" { + elem = elem[l:] + } else { + break + } + + // Param: "new_name" + // Leaf parameter, slashes are prohibited + idx := strings.IndexByte(elem, '/') + if idx >= 0 { + break + } + args[1] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch r.Method { + case "POST": + s.handleRenameUserRequest([2]string{ + args[0], + args[1], + }, elemIsEscaped, w, r) + default: + s.notAllowed(w, r, notAllowedParams{ + allowedMethods: "POST", + allowedHeaders: rn32AllowedHeaders, + acceptPost: "", + acceptPatch: "", + }) + } + + return + } + + } + + } + + } + + } + } + s.notFound(w, r) +} + +// Route is route object. +type Route struct { + name string + summary string + operationID string + operationGroup string + pathPattern string + count int + args [2]string +} + +// Name returns ogen operation name. +// +// It is guaranteed to be unique and not empty. +func (r Route) Name() string { + return r.name +} + +// Summary returns OpenAPI summary. +func (r Route) Summary() string { + return r.summary +} + +// OperationID returns OpenAPI operationId. +func (r Route) OperationID() string { + return r.operationID +} + +// OperationGroup returns the x-ogen-operation-group value. +func (r Route) OperationGroup() string { + return r.operationGroup +} + +// PathPattern returns OpenAPI path. +func (r Route) PathPattern() string { + return r.pathPattern +} + +// Args returns parsed arguments. +func (r Route) Args() []string { + return r.args[:r.count] +} + +// FindRoute finds Route for given method and path. +// +// Note: this method does not unescape path or handle reserved characters in path properly. Use FindPath instead. +func (s *Server) FindRoute(method, path string) (Route, bool) { + return s.FindPath(method, &url.URL{Path: path}) +} + +// FindPath finds Route for given method and URL. +func (s *Server) FindPath(method string, u *url.URL) (r Route, _ bool) { + var ( + elem = u.Path + args = r.args + ) + if rawPath := u.RawPath; rawPath != "" { + if normalized, ok := uri.NormalizeEscapedPath(rawPath); ok { + elem = normalized + } + defer func() { + for i, arg := range r.args[:r.count] { + if unescaped, err := url.PathUnescape(arg); err == nil { + r.args[i] = unescaped + } + } + }() + } + + elem, ok := s.cutPrefix(elem) + if !ok { + return r, false + } + + // Static code generated router with unwrapped path search. + switch { + default: + if len(elem) == 0 { + break + } + switch elem[0] { + case '/': // Prefix: "/api/v1/" + + if l := len("/api/v1/"); len(elem) >= l && elem[0:l] == "/api/v1/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'a': // Prefix: "a" + + if l := len("a"); len(elem) >= l && elem[0:l] == "a" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'p': // Prefix: "pikey" + + if l := len("pikey"); len(elem) >= l && elem[0:l] == "pikey" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "GET": + r.name = ListApiKeysOperation + r.summary = "List all API keys." + r.operationID = "ListApiKeys" + r.operationGroup = "" + r.pathPattern = "/api/v1/apikey" + r.args = args + r.count = 0 + return r, true + case "POST": + r.name = CreateApiKeyOperation + r.summary = "Create an API key." + r.operationID = "CreateApiKey" + r.operationGroup = "" + r.pathPattern = "/api/v1/apikey" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'e': // Prefix: "expire" + origElem := elem + if l := len("expire"); len(elem) >= l && elem[0:l] == "expire" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = ExpireApiKeyOperation + r.summary = "Expire an API key by id or prefix." + r.operationID = "ExpireApiKey" + r.operationGroup = "" + r.pathPattern = "/api/v1/apikey/expire" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + elem = origElem + } + // Param: "prefix" + // Leaf parameter, slashes are prohibited + idx := strings.IndexByte(elem, '/') + if idx >= 0 { + break + } + args[0] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch method { + case "DELETE": + r.name = DeleteApiKeyOperation + r.summary = "Delete an API key by prefix (or id)." + r.operationID = "DeleteApiKey" + r.operationGroup = "" + r.pathPattern = "/api/v1/apikey/{prefix}" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + } + + case 'u': // Prefix: "uth/" + + if l := len("uth/"); len(elem) >= l && elem[0:l] == "uth/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'a': // Prefix: "approve" + + if l := len("approve"); len(elem) >= l && elem[0:l] == "approve" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = AuthApproveOperation + r.summary = "Approve a pending auth session." + r.operationID = "AuthApprove" + r.operationGroup = "" + r.pathPattern = "/api/v1/auth/approve" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + case 'r': // Prefix: "re" + + if l := len("re"); len(elem) >= l && elem[0:l] == "re" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'g': // Prefix: "gister" + + if l := len("gister"); len(elem) >= l && elem[0:l] == "gister" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = AuthRegisterOperation + r.summary = "Register a node via an auth id (alias of RegisterNode)." + r.operationID = "AuthRegister" + r.operationGroup = "" + r.pathPattern = "/api/v1/auth/register" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + case 'j': // Prefix: "ject" + + if l := len("ject"); len(elem) >= l && elem[0:l] == "ject" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = AuthRejectOperation + r.summary = "Reject a pending auth session." + r.operationID = "AuthReject" + r.operationGroup = "" + r.pathPattern = "/api/v1/auth/reject" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + } + + } + + } + + case 'd': // Prefix: "debug/node" + + if l := len("debug/node"); len(elem) >= l && elem[0:l] == "debug/node" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = DebugCreateNodeOperation + r.summary = "Create a debug node and cache its registration (testing only)." + r.operationID = "DebugCreateNode" + r.operationGroup = "" + r.pathPattern = "/api/v1/debug/node" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + case 'h': // Prefix: "health" + + if l := len("health"); len(elem) >= l && elem[0:l] == "health" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "GET": + r.name = HealthOperation + r.summary = "Report server health, including database connectivity." + r.operationID = "Health" + r.operationGroup = "" + r.pathPattern = "/api/v1/health" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + case 'n': // Prefix: "node" + + if l := len("node"); len(elem) >= l && elem[0:l] == "node" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "GET": + r.name = ListNodesOperation + r.summary = "List nodes, optionally filtered by user." + r.operationID = "ListNodes" + r.operationGroup = "" + r.pathPattern = "/api/v1/node" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'b': // Prefix: "backfillips" + origElem := elem + if l := len("backfillips"); len(elem) >= l && elem[0:l] == "backfillips" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = BackfillNodeIPsOperation + r.summary = "Backfill missing IP addresses for all nodes." + r.operationID = "BackfillNodeIPs" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/backfillips" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + elem = origElem + case 'r': // Prefix: "register" + origElem := elem + if l := len("register"); len(elem) >= l && elem[0:l] == "register" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = RegisterNodeOperation + r.summary = "Register a node to a user using a registration id." + r.operationID = "RegisterNode" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/register" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + elem = origElem + } + // Param: "node_id" + // Match until "/" + idx := strings.IndexByte(elem, '/') + if idx < 0 { + idx = len(elem) + } + args[0] = elem[:idx] + elem = elem[idx:] + + if len(elem) == 0 { + switch method { + case "DELETE": + r.name = DeleteNodeOperation + r.summary = "Delete a node." + r.operationID = "DeleteNode" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/{node_id}" + r.args = args + r.count = 1 + return r, true + case "GET": + r.name = GetNodeOperation + r.summary = "Get a node by id." + r.operationID = "GetNode" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/{node_id}" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'a': // Prefix: "approve_routes" + + if l := len("approve_routes"); len(elem) >= l && elem[0:l] == "approve_routes" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = SetApprovedRoutesOperation + r.summary = "Set the approved subnet routes of a node." + r.operationID = "SetApprovedRoutes" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/{node_id}/approve_routes" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + case 'e': // Prefix: "expire" + + if l := len("expire"); len(elem) >= l && elem[0:l] == "expire" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = ExpireNodeOperation + r.summary = "Expire a node, or disable its expiry." + r.operationID = "ExpireNode" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/{node_id}/expire" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + case 'r': // Prefix: "rename/" + + if l := len("rename/"); len(elem) >= l && elem[0:l] == "rename/" { + elem = elem[l:] + } else { + break + } + + // Param: "new_name" + // Leaf parameter, slashes are prohibited + idx := strings.IndexByte(elem, '/') + if idx >= 0 { + break + } + args[1] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = RenameNodeOperation + r.summary = "Rename a node." + r.operationID = "RenameNode" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/{node_id}/rename/{new_name}" + r.args = args + r.count = 2 + return r, true + default: + return + } + } + + case 't': // Prefix: "tags" + + if l := len("tags"); len(elem) >= l && elem[0:l] == "tags" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = SetTagsOperation + r.summary = "Set the tags of a node (converts it to a tagged node)." + r.operationID = "SetTags" + r.operationGroup = "" + r.pathPattern = "/api/v1/node/{node_id}/tags" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + + } + + } + + } + + case 'p': // Prefix: "p" + + if l := len("p"); len(elem) >= l && elem[0:l] == "p" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + break + } + switch elem[0] { + case 'o': // Prefix: "olicy" + + if l := len("olicy"); len(elem) >= l && elem[0:l] == "olicy" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "GET": + r.name = GetPolicyOperation + r.summary = "Get the current ACL policy." + r.operationID = "GetPolicy" + r.operationGroup = "" + r.pathPattern = "/api/v1/policy" + r.args = args + r.count = 0 + return r, true + case "PUT": + r.name = SetPolicyOperation + r.summary = "Set the ACL policy (database policy mode only)." + r.operationID = "SetPolicy" + r.operationGroup = "" + r.pathPattern = "/api/v1/policy" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/check" + + if l := len("/check"); len(elem) >= l && elem[0:l] == "/check" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = CheckPolicyOperation + r.summary = "Validate a policy against live users and nodes without storing it." + r.operationID = "CheckPolicy" + r.operationGroup = "" + r.pathPattern = "/api/v1/policy/check" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + } + + case 'r': // Prefix: "reauthkey" + + if l := len("reauthkey"); len(elem) >= l && elem[0:l] == "reauthkey" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "DELETE": + r.name = DeletePreAuthKeyOperation + r.summary = "Delete a pre-auth key." + r.operationID = "DeletePreAuthKey" + r.operationGroup = "" + r.pathPattern = "/api/v1/preauthkey" + r.args = args + r.count = 0 + return r, true + case "GET": + r.name = ListPreAuthKeysOperation + r.summary = "List all pre-auth keys." + r.operationID = "ListPreAuthKeys" + r.operationGroup = "" + r.pathPattern = "/api/v1/preauthkey" + r.args = args + r.count = 0 + return r, true + case "POST": + r.name = CreatePreAuthKeyOperation + r.summary = "Create a pre-auth key." + r.operationID = "CreatePreAuthKey" + r.operationGroup = "" + r.pathPattern = "/api/v1/preauthkey" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/expire" + + if l := len("/expire"); len(elem) >= l && elem[0:l] == "/expire" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = ExpirePreAuthKeyOperation + r.summary = "Expire a pre-auth key." + r.operationID = "ExpirePreAuthKey" + r.operationGroup = "" + r.pathPattern = "/api/v1/preauthkey/expire" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + + } + + } + + case 'u': // Prefix: "user" + + if l := len("user"); len(elem) >= l && elem[0:l] == "user" { + elem = elem[l:] + } else { + break + } + + if len(elem) == 0 { + switch method { + case "GET": + r.name = ListUsersOperation + r.summary = "List users, optionally filtered by id, name, or email." + r.operationID = "ListUsers" + r.operationGroup = "" + r.pathPattern = "/api/v1/user" + r.args = args + r.count = 0 + return r, true + case "POST": + r.name = CreateUserOperation + r.summary = "Create a user." + r.operationID = "CreateUser" + r.operationGroup = "" + r.pathPattern = "/api/v1/user" + r.args = args + r.count = 0 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/" + + if l := len("/"); len(elem) >= l && elem[0:l] == "/" { + elem = elem[l:] + } else { + break + } + + // Param: "id" + // Match until "/" + idx := strings.IndexByte(elem, '/') + if idx < 0 { + idx = len(elem) + } + args[0] = elem[:idx] + elem = elem[idx:] + + if len(elem) == 0 { + switch method { + case "DELETE": + r.name = DeleteUserOperation + r.summary = "Delete a user." + r.operationID = "DeleteUser" + r.operationGroup = "" + r.pathPattern = "/api/v1/user/{id}" + r.args = args + r.count = 1 + return r, true + default: + return + } + } + switch elem[0] { + case '/': // Prefix: "/rename/" + + if l := len("/rename/"); len(elem) >= l && elem[0:l] == "/rename/" { + elem = elem[l:] + } else { + break + } + + // Param: "new_name" + // Leaf parameter, slashes are prohibited + idx := strings.IndexByte(elem, '/') + if idx >= 0 { + break + } + args[1] = elem + elem = "" + + if len(elem) == 0 { + // Leaf node. + switch method { + case "POST": + r.name = RenameUserOperation + r.summary = "Rename a user." + r.operationID = "RenameUser" + r.operationGroup = "" + r.pathPattern = "/api/v1/user/{old_id}/rename/{new_name}" + r.args = args + r.count = 2 + return r, true + default: + return + } + } + + } + + } + + } + + } + } + return r, false +} diff --git a/gen/api/v1/oas_schemas_gen.go b/gen/api/v1/oas_schemas_gen.go new file mode 100644 index 00000000..159016ab --- /dev/null +++ b/gen/api/v1/oas_schemas_gen.go @@ -0,0 +1,1732 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "fmt" + "net/url" + "time" + + "github.com/go-faster/errors" +) + +func (s *ErrorStatusCode) Error() string { + return fmt.Sprintf("code %d: %+v", s.StatusCode, s.Response) +} + +// Ref: #/components/schemas/ApiKey +type ApiKey struct { + ID OptUint64 `json:"id"` + Prefix OptString `json:"prefix"` + Expiration OptDateTime `json:"expiration"` + CreatedAt OptDateTime `json:"createdAt"` + LastSeen OptDateTime `json:"lastSeen"` +} + +// GetID returns the value of ID. +func (s *ApiKey) GetID() OptUint64 { + return s.ID +} + +// GetPrefix returns the value of Prefix. +func (s *ApiKey) GetPrefix() OptString { + return s.Prefix +} + +// GetExpiration returns the value of Expiration. +func (s *ApiKey) GetExpiration() OptDateTime { + return s.Expiration +} + +// GetCreatedAt returns the value of CreatedAt. +func (s *ApiKey) GetCreatedAt() OptDateTime { + return s.CreatedAt +} + +// GetLastSeen returns the value of LastSeen. +func (s *ApiKey) GetLastSeen() OptDateTime { + return s.LastSeen +} + +// SetID sets the value of ID. +func (s *ApiKey) SetID(val OptUint64) { + s.ID = val +} + +// SetPrefix sets the value of Prefix. +func (s *ApiKey) SetPrefix(val OptString) { + s.Prefix = val +} + +// SetExpiration sets the value of Expiration. +func (s *ApiKey) SetExpiration(val OptDateTime) { + s.Expiration = val +} + +// SetCreatedAt sets the value of CreatedAt. +func (s *ApiKey) SetCreatedAt(val OptDateTime) { + s.CreatedAt = val +} + +// SetLastSeen sets the value of LastSeen. +func (s *ApiKey) SetLastSeen(val OptDateTime) { + s.LastSeen = val +} + +type AuthApproveOK struct{} + +type AuthApproveReq struct { + AuthId OptString `json:"authId"` +} + +// GetAuthId returns the value of AuthId. +func (s *AuthApproveReq) GetAuthId() OptString { + return s.AuthId +} + +// SetAuthId sets the value of AuthId. +func (s *AuthApproveReq) SetAuthId(val OptString) { + s.AuthId = val +} + +type AuthRegisterOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *AuthRegisterOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *AuthRegisterOK) SetNode(val OptNode) { + s.Node = val +} + +type AuthRegisterReq struct { + User OptString `json:"user"` + AuthId OptString `json:"authId"` +} + +// GetUser returns the value of User. +func (s *AuthRegisterReq) GetUser() OptString { + return s.User +} + +// GetAuthId returns the value of AuthId. +func (s *AuthRegisterReq) GetAuthId() OptString { + return s.AuthId +} + +// SetUser sets the value of User. +func (s *AuthRegisterReq) SetUser(val OptString) { + s.User = val +} + +// SetAuthId sets the value of AuthId. +func (s *AuthRegisterReq) SetAuthId(val OptString) { + s.AuthId = val +} + +type AuthRejectOK struct{} + +type AuthRejectReq struct { + AuthId OptString `json:"authId"` +} + +// GetAuthId returns the value of AuthId. +func (s *AuthRejectReq) GetAuthId() OptString { + return s.AuthId +} + +// SetAuthId sets the value of AuthId. +func (s *AuthRejectReq) SetAuthId(val OptString) { + s.AuthId = val +} + +type BackfillNodeIPsOK struct { + Changes []string `json:"changes"` +} + +// GetChanges returns the value of Changes. +func (s *BackfillNodeIPsOK) GetChanges() []string { + return s.Changes +} + +// SetChanges sets the value of Changes. +func (s *BackfillNodeIPsOK) SetChanges(val []string) { + s.Changes = val +} + +type BearerAuth struct { + Token string + Roles []string +} + +// GetToken returns the value of Token. +func (s *BearerAuth) GetToken() string { + return s.Token +} + +// GetRoles returns the value of Roles. +func (s *BearerAuth) GetRoles() []string { + return s.Roles +} + +// SetToken sets the value of Token. +func (s *BearerAuth) SetToken(val string) { + s.Token = val +} + +// SetRoles sets the value of Roles. +func (s *BearerAuth) SetRoles(val []string) { + s.Roles = val +} + +type CheckPolicyOK struct{} + +type CheckPolicyReq struct { + Policy OptString `json:"policy"` +} + +// GetPolicy returns the value of Policy. +func (s *CheckPolicyReq) GetPolicy() OptString { + return s.Policy +} + +// SetPolicy sets the value of Policy. +func (s *CheckPolicyReq) SetPolicy(val OptString) { + s.Policy = val +} + +type CreateApiKeyOK struct { + ApiKey OptString `json:"apiKey"` +} + +// GetApiKey returns the value of ApiKey. +func (s *CreateApiKeyOK) GetApiKey() OptString { + return s.ApiKey +} + +// SetApiKey sets the value of ApiKey. +func (s *CreateApiKeyOK) SetApiKey(val OptString) { + s.ApiKey = val +} + +type CreateApiKeyReq struct { + Expiration OptDateTime `json:"expiration"` +} + +// GetExpiration returns the value of Expiration. +func (s *CreateApiKeyReq) GetExpiration() OptDateTime { + return s.Expiration +} + +// SetExpiration sets the value of Expiration. +func (s *CreateApiKeyReq) SetExpiration(val OptDateTime) { + s.Expiration = val +} + +type CreatePreAuthKeyOK struct { + PreAuthKey OptPreAuthKey `json:"preAuthKey"` +} + +// GetPreAuthKey returns the value of PreAuthKey. +func (s *CreatePreAuthKeyOK) GetPreAuthKey() OptPreAuthKey { + return s.PreAuthKey +} + +// SetPreAuthKey sets the value of PreAuthKey. +func (s *CreatePreAuthKeyOK) SetPreAuthKey(val OptPreAuthKey) { + s.PreAuthKey = val +} + +type CreatePreAuthKeyReq struct { + User OptUint64 `json:"user"` + Reusable OptBool `json:"reusable"` + Ephemeral OptBool `json:"ephemeral"` + Expiration OptDateTime `json:"expiration"` + AclTags []string `json:"aclTags"` +} + +// GetUser returns the value of User. +func (s *CreatePreAuthKeyReq) GetUser() OptUint64 { + return s.User +} + +// GetReusable returns the value of Reusable. +func (s *CreatePreAuthKeyReq) GetReusable() OptBool { + return s.Reusable +} + +// GetEphemeral returns the value of Ephemeral. +func (s *CreatePreAuthKeyReq) GetEphemeral() OptBool { + return s.Ephemeral +} + +// GetExpiration returns the value of Expiration. +func (s *CreatePreAuthKeyReq) GetExpiration() OptDateTime { + return s.Expiration +} + +// GetAclTags returns the value of AclTags. +func (s *CreatePreAuthKeyReq) GetAclTags() []string { + return s.AclTags +} + +// SetUser sets the value of User. +func (s *CreatePreAuthKeyReq) SetUser(val OptUint64) { + s.User = val +} + +// SetReusable sets the value of Reusable. +func (s *CreatePreAuthKeyReq) SetReusable(val OptBool) { + s.Reusable = val +} + +// SetEphemeral sets the value of Ephemeral. +func (s *CreatePreAuthKeyReq) SetEphemeral(val OptBool) { + s.Ephemeral = val +} + +// SetExpiration sets the value of Expiration. +func (s *CreatePreAuthKeyReq) SetExpiration(val OptDateTime) { + s.Expiration = val +} + +// SetAclTags sets the value of AclTags. +func (s *CreatePreAuthKeyReq) SetAclTags(val []string) { + s.AclTags = val +} + +type CreateUserOK struct { + User OptUser `json:"user"` +} + +// GetUser returns the value of User. +func (s *CreateUserOK) GetUser() OptUser { + return s.User +} + +// SetUser sets the value of User. +func (s *CreateUserOK) SetUser(val OptUser) { + s.User = val +} + +type CreateUserReq struct { + Name OptString `json:"name"` + DisplayName OptString `json:"displayName"` + Email OptString `json:"email"` + PictureUrl OptString `json:"pictureUrl"` +} + +// GetName returns the value of Name. +func (s *CreateUserReq) GetName() OptString { + return s.Name +} + +// GetDisplayName returns the value of DisplayName. +func (s *CreateUserReq) GetDisplayName() OptString { + return s.DisplayName +} + +// GetEmail returns the value of Email. +func (s *CreateUserReq) GetEmail() OptString { + return s.Email +} + +// GetPictureUrl returns the value of PictureUrl. +func (s *CreateUserReq) GetPictureUrl() OptString { + return s.PictureUrl +} + +// SetName sets the value of Name. +func (s *CreateUserReq) SetName(val OptString) { + s.Name = val +} + +// SetDisplayName sets the value of DisplayName. +func (s *CreateUserReq) SetDisplayName(val OptString) { + s.DisplayName = val +} + +// SetEmail sets the value of Email. +func (s *CreateUserReq) SetEmail(val OptString) { + s.Email = val +} + +// SetPictureUrl sets the value of PictureUrl. +func (s *CreateUserReq) SetPictureUrl(val OptString) { + s.PictureUrl = val +} + +type DebugCreateNodeOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *DebugCreateNodeOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *DebugCreateNodeOK) SetNode(val OptNode) { + s.Node = val +} + +type DebugCreateNodeReq struct { + User OptString `json:"user"` + Key OptString `json:"key"` + Name OptString `json:"name"` + Routes []string `json:"routes"` +} + +// GetUser returns the value of User. +func (s *DebugCreateNodeReq) GetUser() OptString { + return s.User +} + +// GetKey returns the value of Key. +func (s *DebugCreateNodeReq) GetKey() OptString { + return s.Key +} + +// GetName returns the value of Name. +func (s *DebugCreateNodeReq) GetName() OptString { + return s.Name +} + +// GetRoutes returns the value of Routes. +func (s *DebugCreateNodeReq) GetRoutes() []string { + return s.Routes +} + +// SetUser sets the value of User. +func (s *DebugCreateNodeReq) SetUser(val OptString) { + s.User = val +} + +// SetKey sets the value of Key. +func (s *DebugCreateNodeReq) SetKey(val OptString) { + s.Key = val +} + +// SetName sets the value of Name. +func (s *DebugCreateNodeReq) SetName(val OptString) { + s.Name = val +} + +// SetRoutes sets the value of Routes. +func (s *DebugCreateNodeReq) SetRoutes(val []string) { + s.Routes = val +} + +type DeleteApiKeyOK struct{} + +type DeleteNodeOK struct{} + +type DeletePreAuthKeyOK struct{} + +type DeleteUserOK struct{} + +// ErrorStatusCode wraps Problem with StatusCode. +type ErrorStatusCode struct { + StatusCode int + Response Problem +} + +// GetStatusCode returns the value of StatusCode. +func (s *ErrorStatusCode) GetStatusCode() int { + return s.StatusCode +} + +// GetResponse returns the value of Response. +func (s *ErrorStatusCode) GetResponse() Problem { + return s.Response +} + +// SetStatusCode sets the value of StatusCode. +func (s *ErrorStatusCode) SetStatusCode(val int) { + s.StatusCode = val +} + +// SetResponse sets the value of Response. +func (s *ErrorStatusCode) SetResponse(val Problem) { + s.Response = val +} + +type ExpireApiKeyOK struct{} + +type ExpireApiKeyReq struct { + Prefix OptString `json:"prefix"` + ID OptUint64 `json:"id"` +} + +// GetPrefix returns the value of Prefix. +func (s *ExpireApiKeyReq) GetPrefix() OptString { + return s.Prefix +} + +// GetID returns the value of ID. +func (s *ExpireApiKeyReq) GetID() OptUint64 { + return s.ID +} + +// SetPrefix sets the value of Prefix. +func (s *ExpireApiKeyReq) SetPrefix(val OptString) { + s.Prefix = val +} + +// SetID sets the value of ID. +func (s *ExpireApiKeyReq) SetID(val OptUint64) { + s.ID = val +} + +type ExpireNodeOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *ExpireNodeOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *ExpireNodeOK) SetNode(val OptNode) { + s.Node = val +} + +type ExpirePreAuthKeyOK struct{} + +type ExpirePreAuthKeyReq struct { + ID OptUint64 `json:"id"` +} + +// GetID returns the value of ID. +func (s *ExpirePreAuthKeyReq) GetID() OptUint64 { + return s.ID +} + +// SetID sets the value of ID. +func (s *ExpirePreAuthKeyReq) SetID(val OptUint64) { + s.ID = val +} + +type GetNodeOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *GetNodeOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *GetNodeOK) SetNode(val OptNode) { + s.Node = val +} + +type GetPolicyOK struct { + Policy OptString `json:"policy"` + UpdatedAt OptDateTime `json:"updatedAt"` +} + +// GetPolicy returns the value of Policy. +func (s *GetPolicyOK) GetPolicy() OptString { + return s.Policy +} + +// GetUpdatedAt returns the value of UpdatedAt. +func (s *GetPolicyOK) GetUpdatedAt() OptDateTime { + return s.UpdatedAt +} + +// SetPolicy sets the value of Policy. +func (s *GetPolicyOK) SetPolicy(val OptString) { + s.Policy = val +} + +// SetUpdatedAt sets the value of UpdatedAt. +func (s *GetPolicyOK) SetUpdatedAt(val OptDateTime) { + s.UpdatedAt = val +} + +type HealthOK struct { + DatabaseConnectivity OptBool `json:"databaseConnectivity"` +} + +// GetDatabaseConnectivity returns the value of DatabaseConnectivity. +func (s *HealthOK) GetDatabaseConnectivity() OptBool { + return s.DatabaseConnectivity +} + +// SetDatabaseConnectivity sets the value of DatabaseConnectivity. +func (s *HealthOK) SetDatabaseConnectivity(val OptBool) { + s.DatabaseConnectivity = val +} + +type ListApiKeysOK struct { + ApiKeys []ApiKey `json:"apiKeys"` +} + +// GetApiKeys returns the value of ApiKeys. +func (s *ListApiKeysOK) GetApiKeys() []ApiKey { + return s.ApiKeys +} + +// SetApiKeys sets the value of ApiKeys. +func (s *ListApiKeysOK) SetApiKeys(val []ApiKey) { + s.ApiKeys = val +} + +type ListNodesOK struct { + Nodes []Node `json:"nodes"` +} + +// GetNodes returns the value of Nodes. +func (s *ListNodesOK) GetNodes() []Node { + return s.Nodes +} + +// SetNodes sets the value of Nodes. +func (s *ListNodesOK) SetNodes(val []Node) { + s.Nodes = val +} + +type ListPreAuthKeysOK struct { + PreAuthKeys []PreAuthKey `json:"preAuthKeys"` +} + +// GetPreAuthKeys returns the value of PreAuthKeys. +func (s *ListPreAuthKeysOK) GetPreAuthKeys() []PreAuthKey { + return s.PreAuthKeys +} + +// SetPreAuthKeys sets the value of PreAuthKeys. +func (s *ListPreAuthKeysOK) SetPreAuthKeys(val []PreAuthKey) { + s.PreAuthKeys = val +} + +type ListUsersOK struct { + Users []User `json:"users"` +} + +// GetUsers returns the value of Users. +func (s *ListUsersOK) GetUsers() []User { + return s.Users +} + +// SetUsers sets the value of Users. +func (s *ListUsersOK) SetUsers(val []User) { + s.Users = val +} + +// Ref: #/components/schemas/Node +type Node struct { + ID OptUint64 `json:"id"` + MachineKey OptString `json:"machineKey"` + NodeKey OptString `json:"nodeKey"` + DiscoKey OptString `json:"discoKey"` + IpAddresses []string `json:"ipAddresses"` + Name OptString `json:"name"` + User OptUser `json:"user"` + LastSeen OptDateTime `json:"lastSeen"` + Expiry OptDateTime `json:"expiry"` + PreAuthKey OptPreAuthKey `json:"preAuthKey"` + CreatedAt OptDateTime `json:"createdAt"` + RegisterMethod OptRegisterMethod `json:"registerMethod"` + GivenName OptString `json:"givenName"` + Online OptBool `json:"online"` + ApprovedRoutes []string `json:"approvedRoutes"` + AvailableRoutes []string `json:"availableRoutes"` + SubnetRoutes []string `json:"subnetRoutes"` + Tags []string `json:"tags"` +} + +// GetID returns the value of ID. +func (s *Node) GetID() OptUint64 { + return s.ID +} + +// GetMachineKey returns the value of MachineKey. +func (s *Node) GetMachineKey() OptString { + return s.MachineKey +} + +// GetNodeKey returns the value of NodeKey. +func (s *Node) GetNodeKey() OptString { + return s.NodeKey +} + +// GetDiscoKey returns the value of DiscoKey. +func (s *Node) GetDiscoKey() OptString { + return s.DiscoKey +} + +// GetIpAddresses returns the value of IpAddresses. +func (s *Node) GetIpAddresses() []string { + return s.IpAddresses +} + +// GetName returns the value of Name. +func (s *Node) GetName() OptString { + return s.Name +} + +// GetUser returns the value of User. +func (s *Node) GetUser() OptUser { + return s.User +} + +// GetLastSeen returns the value of LastSeen. +func (s *Node) GetLastSeen() OptDateTime { + return s.LastSeen +} + +// GetExpiry returns the value of Expiry. +func (s *Node) GetExpiry() OptDateTime { + return s.Expiry +} + +// GetPreAuthKey returns the value of PreAuthKey. +func (s *Node) GetPreAuthKey() OptPreAuthKey { + return s.PreAuthKey +} + +// GetCreatedAt returns the value of CreatedAt. +func (s *Node) GetCreatedAt() OptDateTime { + return s.CreatedAt +} + +// GetRegisterMethod returns the value of RegisterMethod. +func (s *Node) GetRegisterMethod() OptRegisterMethod { + return s.RegisterMethod +} + +// GetGivenName returns the value of GivenName. +func (s *Node) GetGivenName() OptString { + return s.GivenName +} + +// GetOnline returns the value of Online. +func (s *Node) GetOnline() OptBool { + return s.Online +} + +// GetApprovedRoutes returns the value of ApprovedRoutes. +func (s *Node) GetApprovedRoutes() []string { + return s.ApprovedRoutes +} + +// GetAvailableRoutes returns the value of AvailableRoutes. +func (s *Node) GetAvailableRoutes() []string { + return s.AvailableRoutes +} + +// GetSubnetRoutes returns the value of SubnetRoutes. +func (s *Node) GetSubnetRoutes() []string { + return s.SubnetRoutes +} + +// GetTags returns the value of Tags. +func (s *Node) GetTags() []string { + return s.Tags +} + +// SetID sets the value of ID. +func (s *Node) SetID(val OptUint64) { + s.ID = val +} + +// SetMachineKey sets the value of MachineKey. +func (s *Node) SetMachineKey(val OptString) { + s.MachineKey = val +} + +// SetNodeKey sets the value of NodeKey. +func (s *Node) SetNodeKey(val OptString) { + s.NodeKey = val +} + +// SetDiscoKey sets the value of DiscoKey. +func (s *Node) SetDiscoKey(val OptString) { + s.DiscoKey = val +} + +// SetIpAddresses sets the value of IpAddresses. +func (s *Node) SetIpAddresses(val []string) { + s.IpAddresses = val +} + +// SetName sets the value of Name. +func (s *Node) SetName(val OptString) { + s.Name = val +} + +// SetUser sets the value of User. +func (s *Node) SetUser(val OptUser) { + s.User = val +} + +// SetLastSeen sets the value of LastSeen. +func (s *Node) SetLastSeen(val OptDateTime) { + s.LastSeen = val +} + +// SetExpiry sets the value of Expiry. +func (s *Node) SetExpiry(val OptDateTime) { + s.Expiry = val +} + +// SetPreAuthKey sets the value of PreAuthKey. +func (s *Node) SetPreAuthKey(val OptPreAuthKey) { + s.PreAuthKey = val +} + +// SetCreatedAt sets the value of CreatedAt. +func (s *Node) SetCreatedAt(val OptDateTime) { + s.CreatedAt = val +} + +// SetRegisterMethod sets the value of RegisterMethod. +func (s *Node) SetRegisterMethod(val OptRegisterMethod) { + s.RegisterMethod = val +} + +// SetGivenName sets the value of GivenName. +func (s *Node) SetGivenName(val OptString) { + s.GivenName = val +} + +// SetOnline sets the value of Online. +func (s *Node) SetOnline(val OptBool) { + s.Online = val +} + +// SetApprovedRoutes sets the value of ApprovedRoutes. +func (s *Node) SetApprovedRoutes(val []string) { + s.ApprovedRoutes = val +} + +// SetAvailableRoutes sets the value of AvailableRoutes. +func (s *Node) SetAvailableRoutes(val []string) { + s.AvailableRoutes = val +} + +// SetSubnetRoutes sets the value of SubnetRoutes. +func (s *Node) SetSubnetRoutes(val []string) { + s.SubnetRoutes = val +} + +// SetTags sets the value of Tags. +func (s *Node) SetTags(val []string) { + s.Tags = val +} + +// NewOptBool returns new OptBool with value set to v. +func NewOptBool(v bool) OptBool { + return OptBool{ + Value: v, + Set: true, + } +} + +// OptBool is optional bool. +type OptBool struct { + Value bool + Set bool +} + +// IsSet returns true if OptBool was set. +func (o OptBool) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptBool) Reset() { + var v bool + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptBool) SetTo(v bool) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptBool) Get() (v bool, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptBool) Or(d bool) bool { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptDateTime returns new OptDateTime with value set to v. +func NewOptDateTime(v time.Time) OptDateTime { + return OptDateTime{ + Value: v, + Set: true, + } +} + +// OptDateTime is optional time.Time. +type OptDateTime struct { + Value time.Time + Set bool +} + +// IsSet returns true if OptDateTime was set. +func (o OptDateTime) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptDateTime) Reset() { + var v time.Time + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptDateTime) SetTo(v time.Time) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptDateTime) Get() (v time.Time, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptDateTime) Or(d time.Time) time.Time { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptInt32 returns new OptInt32 with value set to v. +func NewOptInt32(v int32) OptInt32 { + return OptInt32{ + Value: v, + Set: true, + } +} + +// OptInt32 is optional int32. +type OptInt32 struct { + Value int32 + Set bool +} + +// IsSet returns true if OptInt32 was set. +func (o OptInt32) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptInt32) Reset() { + var v int32 + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptInt32) SetTo(v int32) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptInt32) Get() (v int32, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptInt32) Or(d int32) int32 { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptNode returns new OptNode with value set to v. +func NewOptNode(v Node) OptNode { + return OptNode{ + Value: v, + Set: true, + } +} + +// OptNode is optional Node. +type OptNode struct { + Value Node + Set bool +} + +// IsSet returns true if OptNode was set. +func (o OptNode) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptNode) Reset() { + var v Node + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptNode) SetTo(v Node) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptNode) Get() (v Node, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptNode) Or(d Node) Node { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptPreAuthKey returns new OptPreAuthKey with value set to v. +func NewOptPreAuthKey(v PreAuthKey) OptPreAuthKey { + return OptPreAuthKey{ + Value: v, + Set: true, + } +} + +// OptPreAuthKey is optional PreAuthKey. +type OptPreAuthKey struct { + Value PreAuthKey + Set bool +} + +// IsSet returns true if OptPreAuthKey was set. +func (o OptPreAuthKey) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptPreAuthKey) Reset() { + var v PreAuthKey + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptPreAuthKey) SetTo(v PreAuthKey) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptPreAuthKey) Get() (v PreAuthKey, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptPreAuthKey) Or(d PreAuthKey) PreAuthKey { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptRegisterMethod returns new OptRegisterMethod with value set to v. +func NewOptRegisterMethod(v RegisterMethod) OptRegisterMethod { + return OptRegisterMethod{ + Value: v, + Set: true, + } +} + +// OptRegisterMethod is optional RegisterMethod. +type OptRegisterMethod struct { + Value RegisterMethod + Set bool +} + +// IsSet returns true if OptRegisterMethod was set. +func (o OptRegisterMethod) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptRegisterMethod) Reset() { + var v RegisterMethod + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptRegisterMethod) SetTo(v RegisterMethod) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptRegisterMethod) Get() (v RegisterMethod, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptRegisterMethod) Or(d RegisterMethod) RegisterMethod { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptString returns new OptString with value set to v. +func NewOptString(v string) OptString { + return OptString{ + Value: v, + Set: true, + } +} + +// OptString is optional string. +type OptString struct { + Value string + Set bool +} + +// IsSet returns true if OptString was set. +func (o OptString) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptString) Reset() { + var v string + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptString) SetTo(v string) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptString) Get() (v string, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptString) Or(d string) string { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptURI returns new OptURI with value set to v. +func NewOptURI(v url.URL) OptURI { + return OptURI{ + Value: v, + Set: true, + } +} + +// OptURI is optional url.URL. +type OptURI struct { + Value url.URL + Set bool +} + +// IsSet returns true if OptURI was set. +func (o OptURI) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptURI) Reset() { + var v url.URL + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptURI) SetTo(v url.URL) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptURI) Get() (v url.URL, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptURI) Or(d url.URL) url.URL { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptUint64 returns new OptUint64 with value set to v. +func NewOptUint64(v uint64) OptUint64 { + return OptUint64{ + Value: v, + Set: true, + } +} + +// OptUint64 is optional uint64. +type OptUint64 struct { + Value uint64 + Set bool +} + +// IsSet returns true if OptUint64 was set. +func (o OptUint64) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptUint64) Reset() { + var v uint64 + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptUint64) SetTo(v uint64) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptUint64) Get() (v uint64, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptUint64) Or(d uint64) uint64 { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// NewOptUser returns new OptUser with value set to v. +func NewOptUser(v User) OptUser { + return OptUser{ + Value: v, + Set: true, + } +} + +// OptUser is optional User. +type OptUser struct { + Value User + Set bool +} + +// IsSet returns true if OptUser was set. +func (o OptUser) IsSet() bool { return o.Set } + +// Reset unsets value. +func (o *OptUser) Reset() { + var v User + o.Value = v + o.Set = false +} + +// SetTo sets value to v. +func (o *OptUser) SetTo(v User) { + o.Set = true + o.Value = v +} + +// Get returns value and boolean that denotes whether value was set. +func (o OptUser) Get() (v User, ok bool) { + if !o.Set { + return v, false + } + return o.Value, true +} + +// Or returns value if set, or given parameter if does not. +func (o OptUser) Or(d User) User { + if v, ok := o.Get(); ok { + return v + } + return d +} + +// Ref: #/components/schemas/PreAuthKey +type PreAuthKey struct { + User OptUser `json:"user"` + ID OptUint64 `json:"id"` + Key OptString `json:"key"` + Reusable OptBool `json:"reusable"` + Ephemeral OptBool `json:"ephemeral"` + Used OptBool `json:"used"` + Expiration OptDateTime `json:"expiration"` + CreatedAt OptDateTime `json:"createdAt"` + AclTags []string `json:"aclTags"` +} + +// GetUser returns the value of User. +func (s *PreAuthKey) GetUser() OptUser { + return s.User +} + +// GetID returns the value of ID. +func (s *PreAuthKey) GetID() OptUint64 { + return s.ID +} + +// GetKey returns the value of Key. +func (s *PreAuthKey) GetKey() OptString { + return s.Key +} + +// GetReusable returns the value of Reusable. +func (s *PreAuthKey) GetReusable() OptBool { + return s.Reusable +} + +// GetEphemeral returns the value of Ephemeral. +func (s *PreAuthKey) GetEphemeral() OptBool { + return s.Ephemeral +} + +// GetUsed returns the value of Used. +func (s *PreAuthKey) GetUsed() OptBool { + return s.Used +} + +// GetExpiration returns the value of Expiration. +func (s *PreAuthKey) GetExpiration() OptDateTime { + return s.Expiration +} + +// GetCreatedAt returns the value of CreatedAt. +func (s *PreAuthKey) GetCreatedAt() OptDateTime { + return s.CreatedAt +} + +// GetAclTags returns the value of AclTags. +func (s *PreAuthKey) GetAclTags() []string { + return s.AclTags +} + +// SetUser sets the value of User. +func (s *PreAuthKey) SetUser(val OptUser) { + s.User = val +} + +// SetID sets the value of ID. +func (s *PreAuthKey) SetID(val OptUint64) { + s.ID = val +} + +// SetKey sets the value of Key. +func (s *PreAuthKey) SetKey(val OptString) { + s.Key = val +} + +// SetReusable sets the value of Reusable. +func (s *PreAuthKey) SetReusable(val OptBool) { + s.Reusable = val +} + +// SetEphemeral sets the value of Ephemeral. +func (s *PreAuthKey) SetEphemeral(val OptBool) { + s.Ephemeral = val +} + +// SetUsed sets the value of Used. +func (s *PreAuthKey) SetUsed(val OptBool) { + s.Used = val +} + +// SetExpiration sets the value of Expiration. +func (s *PreAuthKey) SetExpiration(val OptDateTime) { + s.Expiration = val +} + +// SetCreatedAt sets the value of CreatedAt. +func (s *PreAuthKey) SetCreatedAt(val OptDateTime) { + s.CreatedAt = val +} + +// SetAclTags sets the value of AclTags. +func (s *PreAuthKey) SetAclTags(val []string) { + s.AclTags = val +} + +// RFC 7807 problem details. +// Ref: #/components/schemas/Problem +type Problem struct { + Type OptURI `json:"type"` + Title OptString `json:"title"` + Status OptInt32 `json:"status"` + Detail OptString `json:"detail"` + Instance OptURI `json:"instance"` +} + +// GetType returns the value of Type. +func (s *Problem) GetType() OptURI { + return s.Type +} + +// GetTitle returns the value of Title. +func (s *Problem) GetTitle() OptString { + return s.Title +} + +// GetStatus returns the value of Status. +func (s *Problem) GetStatus() OptInt32 { + return s.Status +} + +// GetDetail returns the value of Detail. +func (s *Problem) GetDetail() OptString { + return s.Detail +} + +// GetInstance returns the value of Instance. +func (s *Problem) GetInstance() OptURI { + return s.Instance +} + +// SetType sets the value of Type. +func (s *Problem) SetType(val OptURI) { + s.Type = val +} + +// SetTitle sets the value of Title. +func (s *Problem) SetTitle(val OptString) { + s.Title = val +} + +// SetStatus sets the value of Status. +func (s *Problem) SetStatus(val OptInt32) { + s.Status = val +} + +// SetDetail sets the value of Detail. +func (s *Problem) SetDetail(val OptString) { + s.Detail = val +} + +// SetInstance sets the value of Instance. +func (s *Problem) SetInstance(val OptURI) { + s.Instance = val +} + +// Ref: #/components/schemas/RegisterMethod +type RegisterMethod string + +const ( + RegisterMethodREGISTERMETHODUNSPECIFIED RegisterMethod = "REGISTER_METHOD_UNSPECIFIED" + RegisterMethodREGISTERMETHODAUTHKEY RegisterMethod = "REGISTER_METHOD_AUTH_KEY" + RegisterMethodREGISTERMETHODCLI RegisterMethod = "REGISTER_METHOD_CLI" + RegisterMethodREGISTERMETHODOIDC RegisterMethod = "REGISTER_METHOD_OIDC" +) + +// AllValues returns all RegisterMethod values. +func (RegisterMethod) AllValues() []RegisterMethod { + return []RegisterMethod{ + RegisterMethodREGISTERMETHODUNSPECIFIED, + RegisterMethodREGISTERMETHODAUTHKEY, + RegisterMethodREGISTERMETHODCLI, + RegisterMethodREGISTERMETHODOIDC, + } +} + +// MarshalText implements encoding.TextMarshaler. +func (s RegisterMethod) MarshalText() ([]byte, error) { + switch s { + case RegisterMethodREGISTERMETHODUNSPECIFIED: + return []byte(s), nil + case RegisterMethodREGISTERMETHODAUTHKEY: + return []byte(s), nil + case RegisterMethodREGISTERMETHODCLI: + return []byte(s), nil + case RegisterMethodREGISTERMETHODOIDC: + return []byte(s), nil + default: + return nil, errors.Errorf("invalid value: %q", s) + } +} + +// UnmarshalText implements encoding.TextUnmarshaler. +func (s *RegisterMethod) UnmarshalText(data []byte) error { + switch RegisterMethod(data) { + case RegisterMethodREGISTERMETHODUNSPECIFIED: + *s = RegisterMethodREGISTERMETHODUNSPECIFIED + return nil + case RegisterMethodREGISTERMETHODAUTHKEY: + *s = RegisterMethodREGISTERMETHODAUTHKEY + return nil + case RegisterMethodREGISTERMETHODCLI: + *s = RegisterMethodREGISTERMETHODCLI + return nil + case RegisterMethodREGISTERMETHODOIDC: + *s = RegisterMethodREGISTERMETHODOIDC + return nil + default: + return errors.Errorf("invalid value: %q", data) + } +} + +type RegisterNodeOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *RegisterNodeOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *RegisterNodeOK) SetNode(val OptNode) { + s.Node = val +} + +type RenameNodeOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *RenameNodeOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *RenameNodeOK) SetNode(val OptNode) { + s.Node = val +} + +type RenameUserOK struct { + User OptUser `json:"user"` +} + +// GetUser returns the value of User. +func (s *RenameUserOK) GetUser() OptUser { + return s.User +} + +// SetUser sets the value of User. +func (s *RenameUserOK) SetUser(val OptUser) { + s.User = val +} + +type SetApprovedRoutesOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *SetApprovedRoutesOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *SetApprovedRoutesOK) SetNode(val OptNode) { + s.Node = val +} + +type SetApprovedRoutesReq struct { + Routes []string `json:"routes"` +} + +// GetRoutes returns the value of Routes. +func (s *SetApprovedRoutesReq) GetRoutes() []string { + return s.Routes +} + +// SetRoutes sets the value of Routes. +func (s *SetApprovedRoutesReq) SetRoutes(val []string) { + s.Routes = val +} + +type SetPolicyOK struct { + Policy OptString `json:"policy"` + UpdatedAt OptDateTime `json:"updatedAt"` +} + +// GetPolicy returns the value of Policy. +func (s *SetPolicyOK) GetPolicy() OptString { + return s.Policy +} + +// GetUpdatedAt returns the value of UpdatedAt. +func (s *SetPolicyOK) GetUpdatedAt() OptDateTime { + return s.UpdatedAt +} + +// SetPolicy sets the value of Policy. +func (s *SetPolicyOK) SetPolicy(val OptString) { + s.Policy = val +} + +// SetUpdatedAt sets the value of UpdatedAt. +func (s *SetPolicyOK) SetUpdatedAt(val OptDateTime) { + s.UpdatedAt = val +} + +type SetPolicyReq struct { + Policy OptString `json:"policy"` +} + +// GetPolicy returns the value of Policy. +func (s *SetPolicyReq) GetPolicy() OptString { + return s.Policy +} + +// SetPolicy sets the value of Policy. +func (s *SetPolicyReq) SetPolicy(val OptString) { + s.Policy = val +} + +type SetTagsOK struct { + Node OptNode `json:"node"` +} + +// GetNode returns the value of Node. +func (s *SetTagsOK) GetNode() OptNode { + return s.Node +} + +// SetNode sets the value of Node. +func (s *SetTagsOK) SetNode(val OptNode) { + s.Node = val +} + +type SetTagsReq struct { + Tags []string `json:"tags"` +} + +// GetTags returns the value of Tags. +func (s *SetTagsReq) GetTags() []string { + return s.Tags +} + +// SetTags sets the value of Tags. +func (s *SetTagsReq) SetTags(val []string) { + s.Tags = val +} + +// Ref: #/components/schemas/User +type User struct { + ID OptUint64 `json:"id"` + Name OptString `json:"name"` + CreatedAt OptDateTime `json:"createdAt"` + DisplayName OptString `json:"displayName"` + Email OptString `json:"email"` + ProviderId OptString `json:"providerId"` + Provider OptString `json:"provider"` + ProfilePicUrl OptString `json:"profilePicUrl"` +} + +// GetID returns the value of ID. +func (s *User) GetID() OptUint64 { + return s.ID +} + +// GetName returns the value of Name. +func (s *User) GetName() OptString { + return s.Name +} + +// GetCreatedAt returns the value of CreatedAt. +func (s *User) GetCreatedAt() OptDateTime { + return s.CreatedAt +} + +// GetDisplayName returns the value of DisplayName. +func (s *User) GetDisplayName() OptString { + return s.DisplayName +} + +// GetEmail returns the value of Email. +func (s *User) GetEmail() OptString { + return s.Email +} + +// GetProviderId returns the value of ProviderId. +func (s *User) GetProviderId() OptString { + return s.ProviderId +} + +// GetProvider returns the value of Provider. +func (s *User) GetProvider() OptString { + return s.Provider +} + +// GetProfilePicUrl returns the value of ProfilePicUrl. +func (s *User) GetProfilePicUrl() OptString { + return s.ProfilePicUrl +} + +// SetID sets the value of ID. +func (s *User) SetID(val OptUint64) { + s.ID = val +} + +// SetName sets the value of Name. +func (s *User) SetName(val OptString) { + s.Name = val +} + +// SetCreatedAt sets the value of CreatedAt. +func (s *User) SetCreatedAt(val OptDateTime) { + s.CreatedAt = val +} + +// SetDisplayName sets the value of DisplayName. +func (s *User) SetDisplayName(val OptString) { + s.DisplayName = val +} + +// SetEmail sets the value of Email. +func (s *User) SetEmail(val OptString) { + s.Email = val +} + +// SetProviderId sets the value of ProviderId. +func (s *User) SetProviderId(val OptString) { + s.ProviderId = val +} + +// SetProvider sets the value of Provider. +func (s *User) SetProvider(val OptString) { + s.Provider = val +} + +// SetProfilePicUrl sets the value of ProfilePicUrl. +func (s *User) SetProfilePicUrl(val OptString) { + s.ProfilePicUrl = val +} diff --git a/gen/api/v1/oas_security_gen.go b/gen/api/v1/oas_security_gen.go new file mode 100644 index 00000000..d7695ebb --- /dev/null +++ b/gen/api/v1/oas_security_gen.go @@ -0,0 +1,119 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "context" + "net/http" + "strings" + + "github.com/go-faster/errors" + "github.com/ogen-go/ogen/ogenerrors" +) + +// SecurityHandler is handler for security parameters. +type SecurityHandler interface { + // HandleBearerAuth handles bearerAuth security. + HandleBearerAuth(ctx context.Context, operationName OperationName, t BearerAuth) (context.Context, error) +} + +func findAuthorization(h http.Header, prefix string) (string, bool) { + v, ok := h["Authorization"] + if !ok { + return "", false + } + for _, vv := range v { + scheme, value, ok := strings.Cut(vv, " ") + if !ok || !strings.EqualFold(scheme, prefix) { + continue + } + return value, true + } + return "", false +} + +// operationRolesBearerAuth is a private map storing roles per operation. +var operationRolesBearerAuth = map[string][]string{ + AuthApproveOperation: []string{}, + AuthRegisterOperation: []string{}, + AuthRejectOperation: []string{}, + BackfillNodeIPsOperation: []string{}, + CheckPolicyOperation: []string{}, + CreateApiKeyOperation: []string{}, + CreatePreAuthKeyOperation: []string{}, + CreateUserOperation: []string{}, + DebugCreateNodeOperation: []string{}, + DeleteApiKeyOperation: []string{}, + DeleteNodeOperation: []string{}, + DeletePreAuthKeyOperation: []string{}, + DeleteUserOperation: []string{}, + ExpireApiKeyOperation: []string{}, + ExpireNodeOperation: []string{}, + ExpirePreAuthKeyOperation: []string{}, + GetNodeOperation: []string{}, + GetPolicyOperation: []string{}, + HealthOperation: []string{}, + ListApiKeysOperation: []string{}, + ListNodesOperation: []string{}, + ListPreAuthKeysOperation: []string{}, + ListUsersOperation: []string{}, + RegisterNodeOperation: []string{}, + RenameNodeOperation: []string{}, + RenameUserOperation: []string{}, + SetApprovedRoutesOperation: []string{}, + SetPolicyOperation: []string{}, + SetTagsOperation: []string{}, +} + +// GetRolesForBearerAuth returns the required roles for the given operation. +// +// This is useful for authorization scenarios where you need to know which roles +// are required for an operation. +// +// Example: +// +// requiredRoles := GetRolesForBearerAuth(AddPetOperation) +// +// Returns nil if the operation has no role requirements or if the operation is unknown. +func GetRolesForBearerAuth(operation string) []string { + roles, ok := operationRolesBearerAuth[operation] + if !ok { + return nil + } + // Return a copy to prevent external modification + result := make([]string, len(roles)) + copy(result, roles) + return result +} + +func (s *Server) securityBearerAuth(ctx context.Context, operationName OperationName, req *http.Request) (context.Context, bool, error) { + var t BearerAuth + token, ok := findAuthorization(req.Header, "Bearer") + if !ok { + return ctx, false, nil + } + t.Token = token + t.Roles = operationRolesBearerAuth[operationName] + rctx, err := s.sec.HandleBearerAuth(ctx, operationName, t) + if errors.Is(err, ogenerrors.ErrSkipServerSecurity) { + return nil, false, nil + } else if err != nil { + return nil, false, err + } + return rctx, true, err +} + +// SecuritySource is provider of security values (tokens, passwords, etc.). +type SecuritySource interface { + // BearerAuth provides bearerAuth security value. + BearerAuth(ctx context.Context, operationName OperationName) (BearerAuth, error) +} + +func (s *Client) securityBearerAuth(ctx context.Context, operationName OperationName, req *http.Request) error { + t, err := s.sec.BearerAuth(ctx, operationName) + if err != nil { + return errors.Wrap(err, "security source \"BearerAuth\"") + } + req.Header.Set("Authorization", "Bearer "+t.Token) + return nil +} diff --git a/gen/api/v1/oas_server_gen.go b/gen/api/v1/oas_server_gen.go new file mode 100644 index 00000000..2e8c09d0 --- /dev/null +++ b/gen/api/v1/oas_server_gen.go @@ -0,0 +1,210 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "context" +) + +// Handler handles operations described by OpenAPI v3 specification. +type Handler interface { + // AuthApprove implements AuthApprove operation. + // + // Approve a pending auth session. + // + // POST /api/v1/auth/approve + AuthApprove(ctx context.Context, req *AuthApproveReq) error + // AuthRegister implements AuthRegister operation. + // + // Register a node via an auth id (alias of RegisterNode). + // + // POST /api/v1/auth/register + AuthRegister(ctx context.Context, req *AuthRegisterReq) (*AuthRegisterOK, error) + // AuthReject implements AuthReject operation. + // + // Reject a pending auth session. + // + // POST /api/v1/auth/reject + AuthReject(ctx context.Context, req *AuthRejectReq) error + // BackfillNodeIPs implements BackfillNodeIPs operation. + // + // Backfill missing IP addresses for all nodes. + // + // POST /api/v1/node/backfillips + BackfillNodeIPs(ctx context.Context, params BackfillNodeIPsParams) (*BackfillNodeIPsOK, error) + // CheckPolicy implements CheckPolicy operation. + // + // Validate a policy against live users and nodes without storing it. + // + // POST /api/v1/policy/check + CheckPolicy(ctx context.Context, req *CheckPolicyReq) error + // CreateApiKey implements CreateApiKey operation. + // + // Create an API key. + // + // POST /api/v1/apikey + CreateApiKey(ctx context.Context, req *CreateApiKeyReq) (*CreateApiKeyOK, error) + // CreatePreAuthKey implements CreatePreAuthKey operation. + // + // Create a pre-auth key. + // + // POST /api/v1/preauthkey + CreatePreAuthKey(ctx context.Context, req *CreatePreAuthKeyReq) (*CreatePreAuthKeyOK, error) + // CreateUser implements CreateUser operation. + // + // Create a user. + // + // POST /api/v1/user + CreateUser(ctx context.Context, req *CreateUserReq) (*CreateUserOK, error) + // DebugCreateNode implements DebugCreateNode operation. + // + // Create a debug node and cache its registration (testing only). + // + // POST /api/v1/debug/node + DebugCreateNode(ctx context.Context, req *DebugCreateNodeReq) (*DebugCreateNodeOK, error) + // DeleteApiKey implements DeleteApiKey operation. + // + // Delete an API key by prefix (or id). + // + // DELETE /api/v1/apikey/{prefix} + DeleteApiKey(ctx context.Context, params DeleteApiKeyParams) error + // DeleteNode implements DeleteNode operation. + // + // Delete a node. + // + // DELETE /api/v1/node/{node_id} + DeleteNode(ctx context.Context, params DeleteNodeParams) error + // DeletePreAuthKey implements DeletePreAuthKey operation. + // + // Delete a pre-auth key. + // + // DELETE /api/v1/preauthkey + DeletePreAuthKey(ctx context.Context, params DeletePreAuthKeyParams) error + // DeleteUser implements DeleteUser operation. + // + // Delete a user. + // + // DELETE /api/v1/user/{id} + DeleteUser(ctx context.Context, params DeleteUserParams) error + // ExpireApiKey implements ExpireApiKey operation. + // + // Expire an API key by id or prefix. + // + // POST /api/v1/apikey/expire + ExpireApiKey(ctx context.Context, req *ExpireApiKeyReq) error + // ExpireNode implements ExpireNode operation. + // + // Expire a node, or disable its expiry. + // + // POST /api/v1/node/{node_id}/expire + ExpireNode(ctx context.Context, params ExpireNodeParams) (*ExpireNodeOK, error) + // ExpirePreAuthKey implements ExpirePreAuthKey operation. + // + // Expire a pre-auth key. + // + // POST /api/v1/preauthkey/expire + ExpirePreAuthKey(ctx context.Context, req *ExpirePreAuthKeyReq) error + // GetNode implements GetNode operation. + // + // Get a node by id. + // + // GET /api/v1/node/{node_id} + GetNode(ctx context.Context, params GetNodeParams) (*GetNodeOK, error) + // GetPolicy implements GetPolicy operation. + // + // Get the current ACL policy. + // + // GET /api/v1/policy + GetPolicy(ctx context.Context) (*GetPolicyOK, error) + // Health implements Health operation. + // + // Report server health, including database connectivity. + // + // GET /api/v1/health + Health(ctx context.Context) (*HealthOK, error) + // ListApiKeys implements ListApiKeys operation. + // + // List all API keys. + // + // GET /api/v1/apikey + ListApiKeys(ctx context.Context) (*ListApiKeysOK, error) + // ListNodes implements ListNodes operation. + // + // List nodes, optionally filtered by user. + // + // GET /api/v1/node + ListNodes(ctx context.Context, params ListNodesParams) (*ListNodesOK, error) + // ListPreAuthKeys implements ListPreAuthKeys operation. + // + // List all pre-auth keys. + // + // GET /api/v1/preauthkey + ListPreAuthKeys(ctx context.Context) (*ListPreAuthKeysOK, error) + // ListUsers implements ListUsers operation. + // + // List users, optionally filtered by id, name, or email. + // + // GET /api/v1/user + ListUsers(ctx context.Context, params ListUsersParams) (*ListUsersOK, error) + // RegisterNode implements RegisterNode operation. + // + // Register a node to a user using a registration id. + // + // POST /api/v1/node/register + RegisterNode(ctx context.Context, params RegisterNodeParams) (*RegisterNodeOK, error) + // RenameNode implements RenameNode operation. + // + // Rename a node. + // + // POST /api/v1/node/{node_id}/rename/{new_name} + RenameNode(ctx context.Context, params RenameNodeParams) (*RenameNodeOK, error) + // RenameUser implements RenameUser operation. + // + // Rename a user. + // + // POST /api/v1/user/{old_id}/rename/{new_name} + RenameUser(ctx context.Context, params RenameUserParams) (*RenameUserOK, error) + // SetApprovedRoutes implements SetApprovedRoutes operation. + // + // Set the approved subnet routes of a node. + // + // POST /api/v1/node/{node_id}/approve_routes + SetApprovedRoutes(ctx context.Context, req *SetApprovedRoutesReq, params SetApprovedRoutesParams) (*SetApprovedRoutesOK, error) + // SetPolicy implements SetPolicy operation. + // + // Set the ACL policy (database policy mode only). + // + // PUT /api/v1/policy + SetPolicy(ctx context.Context, req *SetPolicyReq) (*SetPolicyOK, error) + // SetTags implements SetTags operation. + // + // Set the tags of a node (converts it to a tagged node). + // + // POST /api/v1/node/{node_id}/tags + SetTags(ctx context.Context, req *SetTagsReq, params SetTagsParams) (*SetTagsOK, error) + // NewError creates *ErrorStatusCode from error returned by handler. + // + // Used for common default response. + NewError(ctx context.Context, err error) *ErrorStatusCode +} + +// Server implements http server based on OpenAPI v3 specification and +// calls Handler to handle requests. +type Server struct { + h Handler + sec SecurityHandler + baseServer +} + +// NewServer creates new Server. +func NewServer(h Handler, sec SecurityHandler, opts ...ServerOption) (*Server, error) { + s, err := newServerConfig(opts...).baseServer() + if err != nil { + return nil, err + } + return &Server{ + h: h, + sec: sec, + baseServer: s, + }, nil +} diff --git a/gen/api/v1/oas_unimplemented_gen.go b/gen/api/v1/oas_unimplemented_gen.go new file mode 100644 index 00000000..96f6a357 --- /dev/null +++ b/gen/api/v1/oas_unimplemented_gen.go @@ -0,0 +1,283 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "context" + + ht "github.com/ogen-go/ogen/http" +) + +// UnimplementedHandler is no-op Handler which returns http.ErrNotImplemented. +type UnimplementedHandler struct{} + +var _ Handler = UnimplementedHandler{} + +// AuthApprove implements AuthApprove operation. +// +// Approve a pending auth session. +// +// POST /api/v1/auth/approve +func (UnimplementedHandler) AuthApprove(ctx context.Context, req *AuthApproveReq) error { + return ht.ErrNotImplemented +} + +// AuthRegister implements AuthRegister operation. +// +// Register a node via an auth id (alias of RegisterNode). +// +// POST /api/v1/auth/register +func (UnimplementedHandler) AuthRegister(ctx context.Context, req *AuthRegisterReq) (r *AuthRegisterOK, _ error) { + return r, ht.ErrNotImplemented +} + +// AuthReject implements AuthReject operation. +// +// Reject a pending auth session. +// +// POST /api/v1/auth/reject +func (UnimplementedHandler) AuthReject(ctx context.Context, req *AuthRejectReq) error { + return ht.ErrNotImplemented +} + +// BackfillNodeIPs implements BackfillNodeIPs operation. +// +// Backfill missing IP addresses for all nodes. +// +// POST /api/v1/node/backfillips +func (UnimplementedHandler) BackfillNodeIPs(ctx context.Context, params BackfillNodeIPsParams) (r *BackfillNodeIPsOK, _ error) { + return r, ht.ErrNotImplemented +} + +// CheckPolicy implements CheckPolicy operation. +// +// Validate a policy against live users and nodes without storing it. +// +// POST /api/v1/policy/check +func (UnimplementedHandler) CheckPolicy(ctx context.Context, req *CheckPolicyReq) error { + return ht.ErrNotImplemented +} + +// CreateApiKey implements CreateApiKey operation. +// +// Create an API key. +// +// POST /api/v1/apikey +func (UnimplementedHandler) CreateApiKey(ctx context.Context, req *CreateApiKeyReq) (r *CreateApiKeyOK, _ error) { + return r, ht.ErrNotImplemented +} + +// CreatePreAuthKey implements CreatePreAuthKey operation. +// +// Create a pre-auth key. +// +// POST /api/v1/preauthkey +func (UnimplementedHandler) CreatePreAuthKey(ctx context.Context, req *CreatePreAuthKeyReq) (r *CreatePreAuthKeyOK, _ error) { + return r, ht.ErrNotImplemented +} + +// CreateUser implements CreateUser operation. +// +// Create a user. +// +// POST /api/v1/user +func (UnimplementedHandler) CreateUser(ctx context.Context, req *CreateUserReq) (r *CreateUserOK, _ error) { + return r, ht.ErrNotImplemented +} + +// DebugCreateNode implements DebugCreateNode operation. +// +// Create a debug node and cache its registration (testing only). +// +// POST /api/v1/debug/node +func (UnimplementedHandler) DebugCreateNode(ctx context.Context, req *DebugCreateNodeReq) (r *DebugCreateNodeOK, _ error) { + return r, ht.ErrNotImplemented +} + +// DeleteApiKey implements DeleteApiKey operation. +// +// Delete an API key by prefix (or id). +// +// DELETE /api/v1/apikey/{prefix} +func (UnimplementedHandler) DeleteApiKey(ctx context.Context, params DeleteApiKeyParams) error { + return ht.ErrNotImplemented +} + +// DeleteNode implements DeleteNode operation. +// +// Delete a node. +// +// DELETE /api/v1/node/{node_id} +func (UnimplementedHandler) DeleteNode(ctx context.Context, params DeleteNodeParams) error { + return ht.ErrNotImplemented +} + +// DeletePreAuthKey implements DeletePreAuthKey operation. +// +// Delete a pre-auth key. +// +// DELETE /api/v1/preauthkey +func (UnimplementedHandler) DeletePreAuthKey(ctx context.Context, params DeletePreAuthKeyParams) error { + return ht.ErrNotImplemented +} + +// DeleteUser implements DeleteUser operation. +// +// Delete a user. +// +// DELETE /api/v1/user/{id} +func (UnimplementedHandler) DeleteUser(ctx context.Context, params DeleteUserParams) error { + return ht.ErrNotImplemented +} + +// ExpireApiKey implements ExpireApiKey operation. +// +// Expire an API key by id or prefix. +// +// POST /api/v1/apikey/expire +func (UnimplementedHandler) ExpireApiKey(ctx context.Context, req *ExpireApiKeyReq) error { + return ht.ErrNotImplemented +} + +// ExpireNode implements ExpireNode operation. +// +// Expire a node, or disable its expiry. +// +// POST /api/v1/node/{node_id}/expire +func (UnimplementedHandler) ExpireNode(ctx context.Context, params ExpireNodeParams) (r *ExpireNodeOK, _ error) { + return r, ht.ErrNotImplemented +} + +// ExpirePreAuthKey implements ExpirePreAuthKey operation. +// +// Expire a pre-auth key. +// +// POST /api/v1/preauthkey/expire +func (UnimplementedHandler) ExpirePreAuthKey(ctx context.Context, req *ExpirePreAuthKeyReq) error { + return ht.ErrNotImplemented +} + +// GetNode implements GetNode operation. +// +// Get a node by id. +// +// GET /api/v1/node/{node_id} +func (UnimplementedHandler) GetNode(ctx context.Context, params GetNodeParams) (r *GetNodeOK, _ error) { + return r, ht.ErrNotImplemented +} + +// GetPolicy implements GetPolicy operation. +// +// Get the current ACL policy. +// +// GET /api/v1/policy +func (UnimplementedHandler) GetPolicy(ctx context.Context) (r *GetPolicyOK, _ error) { + return r, ht.ErrNotImplemented +} + +// Health implements Health operation. +// +// Report server health, including database connectivity. +// +// GET /api/v1/health +func (UnimplementedHandler) Health(ctx context.Context) (r *HealthOK, _ error) { + return r, ht.ErrNotImplemented +} + +// ListApiKeys implements ListApiKeys operation. +// +// List all API keys. +// +// GET /api/v1/apikey +func (UnimplementedHandler) ListApiKeys(ctx context.Context) (r *ListApiKeysOK, _ error) { + return r, ht.ErrNotImplemented +} + +// ListNodes implements ListNodes operation. +// +// List nodes, optionally filtered by user. +// +// GET /api/v1/node +func (UnimplementedHandler) ListNodes(ctx context.Context, params ListNodesParams) (r *ListNodesOK, _ error) { + return r, ht.ErrNotImplemented +} + +// ListPreAuthKeys implements ListPreAuthKeys operation. +// +// List all pre-auth keys. +// +// GET /api/v1/preauthkey +func (UnimplementedHandler) ListPreAuthKeys(ctx context.Context) (r *ListPreAuthKeysOK, _ error) { + return r, ht.ErrNotImplemented +} + +// ListUsers implements ListUsers operation. +// +// List users, optionally filtered by id, name, or email. +// +// GET /api/v1/user +func (UnimplementedHandler) ListUsers(ctx context.Context, params ListUsersParams) (r *ListUsersOK, _ error) { + return r, ht.ErrNotImplemented +} + +// RegisterNode implements RegisterNode operation. +// +// Register a node to a user using a registration id. +// +// POST /api/v1/node/register +func (UnimplementedHandler) RegisterNode(ctx context.Context, params RegisterNodeParams) (r *RegisterNodeOK, _ error) { + return r, ht.ErrNotImplemented +} + +// RenameNode implements RenameNode operation. +// +// Rename a node. +// +// POST /api/v1/node/{node_id}/rename/{new_name} +func (UnimplementedHandler) RenameNode(ctx context.Context, params RenameNodeParams) (r *RenameNodeOK, _ error) { + return r, ht.ErrNotImplemented +} + +// RenameUser implements RenameUser operation. +// +// Rename a user. +// +// POST /api/v1/user/{old_id}/rename/{new_name} +func (UnimplementedHandler) RenameUser(ctx context.Context, params RenameUserParams) (r *RenameUserOK, _ error) { + return r, ht.ErrNotImplemented +} + +// SetApprovedRoutes implements SetApprovedRoutes operation. +// +// Set the approved subnet routes of a node. +// +// POST /api/v1/node/{node_id}/approve_routes +func (UnimplementedHandler) SetApprovedRoutes(ctx context.Context, req *SetApprovedRoutesReq, params SetApprovedRoutesParams) (r *SetApprovedRoutesOK, _ error) { + return r, ht.ErrNotImplemented +} + +// SetPolicy implements SetPolicy operation. +// +// Set the ACL policy (database policy mode only). +// +// PUT /api/v1/policy +func (UnimplementedHandler) SetPolicy(ctx context.Context, req *SetPolicyReq) (r *SetPolicyOK, _ error) { + return r, ht.ErrNotImplemented +} + +// SetTags implements SetTags operation. +// +// Set the tags of a node (converts it to a tagged node). +// +// POST /api/v1/node/{node_id}/tags +func (UnimplementedHandler) SetTags(ctx context.Context, req *SetTagsReq, params SetTagsParams) (r *SetTagsOK, _ error) { + return r, ht.ErrNotImplemented +} + +// NewError creates *ErrorStatusCode from error returned by handler. +// +// Used for common default response. +func (UnimplementedHandler) NewError(ctx context.Context, err error) (r *ErrorStatusCode) { + r = new(ErrorStatusCode) + return r +} diff --git a/gen/api/v1/oas_validators_gen.go b/gen/api/v1/oas_validators_gen.go new file mode 100644 index 00000000..06bdc338 --- /dev/null +++ b/gen/api/v1/oas_validators_gen.go @@ -0,0 +1,332 @@ +// Code generated by ogen, DO NOT EDIT. + +package apiv1 + +import ( + "fmt" + + "github.com/go-faster/errors" + "github.com/ogen-go/ogen/validate" +) + +func (s *AuthRegisterOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *DebugCreateNodeOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *ExpireNodeOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *GetNodeOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *ListNodesOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + var failures []validate.FieldError + for i, elem := range s.Nodes { + if err := func() error { + if err := elem.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: fmt.Sprintf("[%d]", i), + Error: err, + }) + } + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "nodes", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *Node) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.RegisterMethod.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "registerMethod", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s RegisterMethod) Validate() error { + switch s { + case "REGISTER_METHOD_UNSPECIFIED": + return nil + case "REGISTER_METHOD_AUTH_KEY": + return nil + case "REGISTER_METHOD_CLI": + return nil + case "REGISTER_METHOD_OIDC": + return nil + default: + return errors.Errorf("invalid value: %v", s) + } +} + +func (s *RegisterNodeOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *RenameNodeOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *SetApprovedRoutesOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} + +func (s *SetTagsOK) Validate() error { + if s == nil { + return validate.ErrNilPointer + } + + var failures []validate.FieldError + if err := func() error { + if value, ok := s.Node.Get(); ok { + if err := func() error { + if err := value.Validate(); err != nil { + return err + } + return nil + }(); err != nil { + return err + } + } + return nil + }(); err != nil { + failures = append(failures, validate.FieldError{ + Name: "node", + Error: err, + }) + } + if len(failures) > 0 { + return &validate.Error{Fields: failures} + } + return nil +} diff --git a/go.mod b/go.mod index bf7794df..73e6ea79 100644 --- a/go.mod +++ b/go.mod @@ -134,16 +134,22 @@ require ( github.com/dblohm7/wingoes v0.0.0-20250822163801-6d8e6105c62d // indirect github.com/dgryski/go-metro v0.0.0-20250106013310-edb8663e5e33 // indirect github.com/distribution/reference v0.6.0 // indirect + github.com/dlclark/regexp2 v1.12.0 // indirect github.com/docker/cli v29.5.3+incompatible // indirect github.com/docker/go-connections v0.7.0 // indirect github.com/docker/go-units v0.5.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect + github.com/fatih/color v1.19.0 // indirect github.com/felixge/fgprof v0.9.5 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fogleman/gg v1.3.0 // indirect github.com/fxamacker/cbor/v2 v2.9.0 // indirect github.com/gaissmai/bart v0.26.1 // indirect + github.com/ghodss/yaml v1.0.0 // indirect github.com/glebarez/go-sqlite v1.22.0 // indirect + github.com/go-faster/errors v0.7.1 // indirect + github.com/go-faster/jx v1.2.0 // indirect + github.com/go-faster/yaml v0.4.6 // indirect github.com/go-jose/go-jose/v3 v3.0.5 // indirect github.com/go-jose/go-jose/v4 v4.1.4 // indirect github.com/go-logr/logr v1.4.3 // indirect @@ -195,6 +201,7 @@ require ( github.com/morikuni/aec v1.1.0 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/ncruces/go-strftime v1.0.0 // indirect + github.com/ogen-go/ogen v1.22.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/opencontainers/runc v1.3.2 // indirect @@ -209,6 +216,8 @@ require ( github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/safchain/ethtool v0.7.0 // indirect github.com/sagikazarmark/locafero v0.12.0 // indirect + github.com/segmentio/asm v1.2.1 // indirect + github.com/shopspring/decimal v1.4.0 // indirect github.com/sirupsen/logrus v1.9.4 // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/spf13/afero v1.15.0 // indirect @@ -227,32 +236,37 @@ require ( github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect github.com/xeipuuv/gojsonschema v1.2.0 // indirect github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect + github.com/yuin/goldmark v1.8.2 // indirect go.opentelemetry.io/auto/sdk v1.2.1 // indirect go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 // indirect go.opentelemetry.io/otel v1.44.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.43.0 // indirect go.opentelemetry.io/otel/metric v1.44.0 // indirect go.opentelemetry.io/otel/trace v1.44.0 // indirect + go.uber.org/multierr v1.11.0 // indirect + go.uber.org/zap v1.28.0 // indirect go.yaml.in/yaml/v2 v2.4.4 // indirect go.yaml.in/yaml/v3 v3.0.4 // indirect go4.org/mem v0.0.0-20240501181205-ae6ca9944745 // indirect golang.org/x/exp/typeparams v0.0.0-20260603202125-055de637280b // indirect golang.org/x/image v0.41.0 // indirect - golang.org/x/mod v0.36.0 // indirect + golang.org/x/mod v0.37.0 // indirect golang.org/x/sys v0.46.0 // indirect golang.org/x/term v0.44.0 // indirect golang.org/x/text v0.38.0 // indirect golang.org/x/time v0.15.0 // indirect - golang.org/x/tools v0.45.0 // indirect + golang.org/x/tools v0.46.0 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20260526163538-3dc84a4a5aaa // indirect + gopkg.in/yaml.v2 v2.4.0 // indirect k8s.io/client-go v0.34.0 // indirect sigs.k8s.io/yaml v1.6.0 // indirect software.sslmate.com/src/go-pkcs12 v0.4.0 // indirect ) tool ( + github.com/ogen-go/ogen/cmd/ogen golang.org/x/tools/cmd/stress golang.org/x/tools/cmd/stringer tailscale.com/cmd/tailscale diff --git a/go.sum b/go.sum index 2de56cbe..90325ccd 100644 --- a/go.sum +++ b/go.sum @@ -146,6 +146,8 @@ github.com/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5Qvfr github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E= github.com/djherbis/times v1.6.0 h1:w2ctJ92J8fBvWPxugmXIv7Nz7Q3iDMKNx9v5ocVH20c= github.com/djherbis/times v1.6.0/go.mod h1:gOHeRAz2h+VJNZ5Gmc/o7iD9k4wW7NMVqieYCY99oc0= +github.com/dlclark/regexp2 v1.12.0 h1:0j4c5qQmnC6XOWNjP3PIXURXN2gWx76rd3KvgdPkCz8= +github.com/dlclark/regexp2 v1.12.0/go.mod h1:DHkYz0B9wPfa6wondMfaivmHpzrQ3v9q8cnmRbL6yW8= github.com/docker/cli v29.5.3+incompatible h1:nbEFfz774vBwQ5KRYv7c/AghjReqnGISvrRhzjV0evs= github.com/docker/cli v29.5.3+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8= github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= @@ -156,6 +158,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= +github.com/fatih/color v1.19.0 h1:Zp3PiM21/9Ld6FzSKyL5c/BULoe/ONr9KlbYVOfG8+w= +github.com/fatih/color v1.19.0/go.mod h1:zNk67I0ZUT1bEGsSGyCZYZNrHuTkJJB+r6Q9VuMi0LE= github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw= github.com/felixge/fgprof v0.9.5 h1:8+vR6yu2vvSKn08urWyEuxx75NWPEvybbkBirEpsbVY= github.com/felixge/fgprof v0.9.5/go.mod h1:yKl+ERSa++RYOs32d8K6WEXCB4uXdLls4ZaZPpayhMM= @@ -171,6 +175,8 @@ github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sa github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ= github.com/gaissmai/bart v0.26.1 h1:+w4rnLGNlA2GDVn382Tfe3jOsK5vOr5n4KmigJ9lbTo= github.com/gaissmai/bart v0.26.1/go.mod h1:GREWQfTLRWz/c5FTOsIw+KkscuFkIV5t8Rp7Nd1Td5c= +github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk= +github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/github/fakeca v0.1.0 h1:Km/MVOFvclqxPM9dZBC4+QE564nU4gz4iZ0D9pMw28I= github.com/github/fakeca v0.1.0/go.mod h1:+bormgoGMMuamOscx7N91aOuUST7wdaJ2rNjeohylyo= github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= @@ -181,6 +187,12 @@ github.com/go-chi/chi/v5 v5.3.0 h1:halUjDxhshgXHMrao5bB8eNBXo/rnzwr8m5m36glehM= github.com/go-chi/chi/v5 v5.3.0/go.mod h1:R+tYY2hNuVUUjxoPtqUdgBqevM9s9njzkTLutVsOCto= github.com/go-chi/metrics v0.1.1 h1:CXhbnkAVVjb0k73EBRQ6Z2YdWFnbXZgNtg1Mboguibk= github.com/go-chi/metrics v0.1.1/go.mod h1:mcGTM1pPalP7WCtb+akNYFO/lwNwBBLCuedepqjoPn4= +github.com/go-faster/errors v0.7.1 h1:MkJTnDoEdi9pDabt1dpWf7AA8/BaSYZqibYyhZ20AYg= +github.com/go-faster/errors v0.7.1/go.mod h1:5ySTjWFiphBs07IKuiL69nxdfd5+fzh1u7FPGZP2quo= +github.com/go-faster/jx v1.2.0 h1:T2YHJPrFaYu21fJtUxC9GzmluKu8rVIFDwwGBKTDseI= +github.com/go-faster/jx v1.2.0/go.mod h1:UWLOVDmMG597a5tBFPLIWJdUxz5/2emOpfsj9Neg0PE= +github.com/go-faster/yaml v0.4.6 h1:lOK/EhI04gCpPgPhgt0bChS6bvw7G3WwI8xxVe0sw9I= +github.com/go-faster/yaml v0.4.6/go.mod h1:390dRIvV4zbnO7qC9FGo6YYutc+wyyUSHBgbXL52eXk= github.com/go-gormigrate/gormigrate/v2 v2.1.6 h1:VtX+l1Stj2v5RGubVQk0LS/8EPGXR+ldcOyCmlmKoyg= github.com/go-gormigrate/gormigrate/v2 v2.1.6/go.mod h1:PZpedQc4tWaxn6kvXicwhinh3L0seLpMc5ReKRX5id4= github.com/go-jose/go-jose/v3 v3.0.5 h1:BLLJWbC4nMZOfuPVxoZIxeYsn6Nl2r1fITaJ78UQlVQ= @@ -355,6 +367,8 @@ github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8= github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25 h1:9bCMuD3TcnjeqjPT2gSlha4asp8NvgcFRYExCaikCxk= github.com/oauth2-proxy/mockoidc v0.0.0-20240214162133-caebfff84d25/go.mod h1:eDjgYHYDJbPLBLsyZ6qRaugP0mX8vePOhZ5id1fdzJw= +github.com/ogen-go/ogen v1.22.0 h1:7wU+jcIKg/JBAhM95909ULLdAkGr43KQOuvNpJ7Mxb4= +github.com/ogen-go/ogen v1.22.0/go.mod h1:7BOh9a51QiPCC92RMrj1LlkLjejhBAyPhR+oMc6lR9g= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -415,8 +429,12 @@ github.com/samber/lo v1.53.0 h1:t975lj2py4kJPQ6haz1QMgtId2gtmfktACxIXArw3HM= github.com/samber/lo v1.53.0/go.mod h1:4+MXEGsJzbKGaUEQFKBq2xtfuznW9oz/WrgyzMzRoM0= github.com/sasha-s/go-deadlock v0.3.9 h1:fiaT9rB7g5sr5ddNZvlwheclN9IP86eFW9WgqlEQV+w= github.com/sasha-s/go-deadlock v0.3.9/go.mod h1:KuZj51ZFmx42q/mPaYbRk0P1xcwe697zsJKE03vD4/Y= +github.com/segmentio/asm v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0= +github.com/segmentio/asm v1.2.1/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs= github.com/sergi/go-diff v1.4.0 h1:n/SP9D5ad1fORl+llWyN+D6qoUETXNZARKjyY2/KVCw= github.com/sergi/go-diff v1.4.0/go.mod h1:A0bzQcvG0E7Rwjx0REVgAGH58e96+X0MeOfepqsbeW4= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= github.com/sirupsen/logrus v1.9.4 h1:TsZE7l11zFCLZnZ+teH4Umoq5BhEIfIzfRDZ1Uzql2w= github.com/sirupsen/logrus v1.9.4/go.mod h1:ftWc9WdOfJ0a92nsE2jF5u5ZwH8Bv2zdeOC42RjbV2g= github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e h1:MRM5ITcdelLK2j1vwZ3Je0FKVCfqOLp5zO6trqMLYs0= @@ -498,6 +516,8 @@ github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQ github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +github.com/yuin/goldmark v1.8.2 h1:kEGpgqJXdgbkhcOgBxkC0X0PmoPG1ZyoZ117rDVp4zE= +github.com/yuin/goldmark v1.8.2/go.mod h1:ip/1k0VRfGynBgxOz0yCqHrbZXhcjxyuS66Brc7iBKg= go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64= go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.69.0 h1:8tvICD4vSTOOsNrsI4Ljf6C+6UKvpTEH5XY3JMoyPoo= @@ -520,6 +540,10 @@ go.opentelemetry.io/proto/otlp v1.10.0 h1:IQRWgT5srOCYfiWnpqUYz9CVmbO8bFmKcwYxpu go.opentelemetry.io/proto/otlp v1.10.0/go.mod h1:/CV4QoCR/S9yaPj8utp3lvQPoqMtxXdzn7ozvvozVqk= go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +go.uber.org/zap v1.28.0 h1:IZzaP1Fv73/T/pBMLk4VutPl36uNC+OSUh3JLG3FIjo= +go.uber.org/zap v1.28.0/go.mod h1:rDLpOi171uODNm/mxFcuYWxDsqWSAVkFdX4XojSKg/Q= go.yaml.in/yaml/v2 v2.4.4 h1:tuyd0P+2Ont/d6e2rl3be67goVK4R6deVxCUX5vyPaQ= go.yaml.in/yaml/v2 v2.4.4/go.mod h1:gMZqIpDtDqOfM0uNfy0SkpRhvUryYH0Z6wdMYcacYXQ= go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc= @@ -543,6 +567,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.36.0 h1:JJjpVx6myfUsUdAzZuOSTTmRE0PfZeNWzzvKrP7amb4= golang.org/x/mod v0.36.0/go.mod h1:moc6ELqsWcOw5Ef3xVprK5ul/MvtVvkIXLziUOICjUQ= +golang.org/x/mod v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ= +golang.org/x/mod v0.37.0/go.mod h1:m8S8VeM9r4dzDwjrKO0a1sZP3YjeMamRRlD+fmR2Q/0= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= @@ -596,6 +622,8 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= golang.org/x/tools v0.45.0 h1:18qN3FAooORvApf5XjCXgsuayZOEtXf6JK18I3+ONa8= golang.org/x/tools v0.45.0/go.mod h1:LuUGqqaXcXMEFEruIVJVm5mgDD8vww/z/SR1gQ4uE/0= +golang.org/x/tools v0.46.0 h1:7jTurBkPZu4moS/Uy4OQT1M+QBlsj3wejyZwsT8Z7rk= +golang.org/x/tools v0.46.0/go.mod h1:FrD85F8l+NWL+9XWBSyVSHO6Ne4jutsfIFba7AWQ5Ys= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 h1:B82qJJgjvYKsXS9jeunTOisW56dUokqW/FOteYJJ/yg= golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2/go.mod h1:deeaetjYA+DHMHg+sMSMI58GrEteJUUzzw7en6TJQcI=