Documentation
¶
Overview ¶
Package httpapi provides primitives to interact with the openapi HTTP API.
Code generated by github.com/oapi-codegen/oapi-codegen/v2 version v2.8.0 DO NOT EDIT.
Package httpapi is the HTTP surface of the Reporting API: the router, the middleware stack every request passes through, and the handlers behind the generated routes.
The contract in api/reporting/openapi.yaml drives both halves of this package. openapi.gen.go carries the routes generated from it, and the same document validates every incoming request at runtime, so a request that the contract does not describe never reaches a handler.
Errors leave as RFC 9457 problems (see the problem subpackage), which is what makes a validation failure, a panic, and an unreachable database look alike to a client.
The normative specification is roadmap/00-conventions.md section 7.
Index ¶
- func GetSpec() (swagger *openapi3.T, err error)
- func GetSpecJSON() ([]byte, error)
- func GetSwagger() (*openapi3.T, error)deprecated
- func Handler(si ServerInterface) http.Handler
- func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler
- func HandlerFromMuxWithBaseURL(si ServerInterface, r chi.Router, baseURL string) http.Handler
- func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler
- func Logger(ctx context.Context) *slog.Logger
- func NewRouter(opts Options) (http.Handler, error)
- func PathToRawSpec(pathToFile string) map[string]func() ([]byte, error)
- func RequestID(ctx context.Context) string
- type ChiServerOptions
- type CreateProject
- type CreateProjectJSONRequestBody
- type CreateProjectRelationJSONRequestBody
- type CreateRelation
- type Cursor
- type DB
- type DeadLetterList
- type DeadLetteredEvent
- type EventInput
- type EventList
- type EventStatsItem
- type EventStatsList
- type GetEventStatsParams
- type GetEventStatsParamsGroupBy
- type GetEventStatsParamsInterval
- type GetProjectSummaryParams
- type GetResourceStatsParams
- type GetResourceStatsParamsGroupBy
- type GetResourceStatsParamsStatus
- type IngestEventsJSONBody
- func (t IngestEventsJSONBody) AsEventInput() (EventInput, error)
- func (t IngestEventsJSONBody) AsIngestEventsJSONBody1() (IngestEventsJSONBody1, error)
- func (t *IngestEventsJSONBody) FromEventInput(v EventInput) error
- func (t *IngestEventsJSONBody) FromIngestEventsJSONBody1(v IngestEventsJSONBody1) error
- func (t IngestEventsJSONBody) MarshalJSON() ([]byte, error)
- func (t *IngestEventsJSONBody) MergeEventInput(v EventInput) error
- func (t *IngestEventsJSONBody) MergeIngestEventsJSONBody1(v IngestEventsJSONBody1) error
- func (t *IngestEventsJSONBody) UnmarshalJSON(b []byte) error
- type IngestEventsJSONBody1
- type IngestEventsJSONRequestBody
- type IngestResult
- type InvalidParamFormatError
- type Lifecycle
- type LifecycleInterval
- type ListEventsParams
- type ListEventsParamsSource
- type ListProjectRelationsParams
- type ListProjectRelationsParamsDirection
- type ListProjectsParams
- type ListRejectedEventsParams
- type ListRelatedProjectsParams
- type ListResourcesParams
- type ListResourcesParamsStatus
- type MiddlewareFunc
- type Options
- type Problem
- type Project
- type ProjectActivity
- type ProjectList
- type ProjectRef
- type ProjectSummary
- type PutResourceTypeJSONRequestBody
- type RebuildProjectionJSONRequestBody
- type RebuildRequest
- type RebuildResult
- type RegisterResourceType
- type RejectedEvent
- type RelatedProject
- type RelatedProjectList
- type Relation
- type RelationList
- type RequiredHeaderError
- type RequiredParamError
- type Resource
- type ResourceList
- type ResourceStatsItem
- type ResourceStatsList
- type ResourceType
- type ResourceTypeList
- type ServerInterface
- type ServerInterfaceWrapper
- func (siw *ServerInterfaceWrapper) CreateProject(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) CreateProjectRelation(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) DeleteProjectRelation(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) GetEventStats(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) GetProject(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) GetProjectSummary(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) GetResourceLifecycle(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) GetResourceStats(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) GetResourceType(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) Healthz(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) IngestEvents(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListEvents(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListProjectRelations(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListProjects(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListRejectedEvents(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListRelatedProjects(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListResourceEvents(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListResourceTypes(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) ListResources(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) Metrics(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) PutResourceType(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) Readyz(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) RebuildProjection(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) SyncCloud(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) UpdateProject(w http.ResponseWriter, r *http.Request)
- func (siw *ServerInterfaceWrapper) UpdateProjectRelation(w http.ResponseWriter, r *http.Request)
- type StoredEvent
- type SyncCloudJSONRequestBody
- type SyncRequest
- type SyncResult
- type SyncStats
- type TooManyValuesForParamError
- type UnescapedCookieParamError
- type Unimplemented
- func (_ Unimplemented) CreateProject(w http.ResponseWriter, r *http.Request)
- func (_ Unimplemented) CreateProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid)
- func (_ Unimplemented) DeleteProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid, relationId Uuid)
- func (_ Unimplemented) GetEventStats(w http.ResponseWriter, r *http.Request, params GetEventStatsParams)
- func (_ Unimplemented) GetProject(w http.ResponseWriter, r *http.Request, id Uuid)
- func (_ Unimplemented) GetProjectSummary(w http.ResponseWriter, r *http.Request, id Uuid, ...)
- func (_ Unimplemented) GetResourceLifecycle(w http.ResponseWriter, r *http.Request, cloud string, resourceType string, ...)
- func (_ Unimplemented) GetResourceStats(w http.ResponseWriter, r *http.Request, params GetResourceStatsParams)
- func (_ Unimplemented) GetResourceType(w http.ResponseWriter, r *http.Request, platform string, resourceType string)
- func (_ Unimplemented) Healthz(w http.ResponseWriter, r *http.Request)
- func (_ Unimplemented) IngestEvents(w http.ResponseWriter, r *http.Request)
- func (_ Unimplemented) ListEvents(w http.ResponseWriter, r *http.Request, params ListEventsParams)
- func (_ Unimplemented) ListProjectRelations(w http.ResponseWriter, r *http.Request, id Uuid, ...)
- func (_ Unimplemented) ListProjects(w http.ResponseWriter, r *http.Request, params ListProjectsParams)
- func (_ Unimplemented) ListRejectedEvents(w http.ResponseWriter, r *http.Request, params ListRejectedEventsParams)
- func (_ Unimplemented) ListRelatedProjects(w http.ResponseWriter, r *http.Request, id Uuid, ...)
- func (_ Unimplemented) ListResourceEvents(w http.ResponseWriter, r *http.Request, cloud string, resourceType string, ...)
- func (_ Unimplemented) ListResourceTypes(w http.ResponseWriter, r *http.Request)
- func (_ Unimplemented) ListResources(w http.ResponseWriter, r *http.Request, params ListResourcesParams)
- func (_ Unimplemented) Metrics(w http.ResponseWriter, r *http.Request)
- func (_ Unimplemented) PutResourceType(w http.ResponseWriter, r *http.Request, platform string, resourceType string)
- func (_ Unimplemented) Readyz(w http.ResponseWriter, r *http.Request)
- func (_ Unimplemented) RebuildProjection(w http.ResponseWriter, r *http.Request)
- func (_ Unimplemented) SyncCloud(w http.ResponseWriter, r *http.Request, cloud string)
- func (_ Unimplemented) UpdateProject(w http.ResponseWriter, r *http.Request, id Uuid)
- func (_ Unimplemented) UpdateProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid, relationId Uuid)
- type UnmarshalingParamError
- type UpdateProject
- type UpdateProjectJSONRequestBody
- type UpdateProjectRelationJSONRequestBody
- type UpdateRelation
- type Uuid
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func GetSpec ¶
GetSpec returns the OpenAPI specification corresponding to the generated code in this file. External references in the spec are resolved through PathToRawSpec; externally-referenced files must be embedded in their corresponding Go packages (via the import-mapping feature). URL-based external refs are not supported.
func GetSpecJSON ¶
GetSpecJSON returns the raw JSON bytes of the embedded OpenAPI specification: decompressed but not unmarshaled. External references are not resolved here; the bytes are the spec exactly as embedded by codegen. The result is cached at package init time, so repeated calls are cheap.
func GetSwagger
deprecated
func Handler ¶
func Handler(si ServerInterface) http.Handler
Handler creates http.Handler with routing matching OpenAPI spec.
func HandlerFromMux ¶
func HandlerFromMux(si ServerInterface, r chi.Router) http.Handler
HandlerFromMux creates http.Handler with routing matching OpenAPI spec based on the provided mux.
func HandlerWithOptions ¶
func HandlerWithOptions(si ServerInterface, options ChiServerOptions) http.Handler
HandlerWithOptions creates http.Handler with additional options
func Logger ¶
Logger returns the logger of the request ctx belongs to, which carries the request id. It falls back to the default logger outside a request, so a caller never has to nil-check it.
func NewRouter ¶
NewRouter assembles the API: the middleware stack, the request validator, and the generated routes.
It fails when the embedded contract does not load or does not validate. That keeps a broken contract from starting a server whose request validation is weaker than the document promises.
func PathToRawSpec ¶
Constructs a synthetic filesystem for resolving external references when loading openapi specifications.
Types ¶
type ChiServerOptions ¶
type ChiServerOptions struct {
BaseURL string
BaseRouter chi.Router
Middlewares []MiddlewareFunc
ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)
}
type CreateProject ¶
type CreateProject struct {
// Cloud The installation the project lives in, os-prod-eu1 for example. A virtual project carries its platform here, and no real project carries `meta` or `partner`.
Cloud string `json:"cloud"`
// ExternalId The project as its cloud names it.
ExternalId string `json:"external_id"`
// Metadata Whatever else is worth keeping about the project. A registration that leaves it out stores the empty object.
// The stored document is bounded at 65536 bytes as the database normalizes it: a number a body spells as an exponent is stored, and answered, spelled out. A write whose document is past the bound is answered 422 and stores nothing.
Metadata *map[string]interface{} `json:"metadata,omitempty"`
// Name What the project is called.
Name *string `json:"name,omitempty"`
// Platform The platform the project lives on, openstack for example. `meta` and `partner` are reserved for the two kinds of virtual project that own no resources: the meta-project and the partner.
Platform string `json:"platform"`
}
CreateProject The project to register. Its `(cloud, external_id)` pair has to be one the registry does not hold yet.
type CreateProjectJSONRequestBody ¶
type CreateProjectJSONRequestBody = CreateProject
CreateProjectJSONRequestBody defines body for CreateProject for application/json ContentType.
type CreateProjectRelationJSONRequestBody ¶
type CreateProjectRelationJSONRequestBody = CreateRelation
CreateProjectRelationJSONRequestBody defines body for CreateProjectRelation for application/json ContentType.
type CreateRelation ¶
type CreateRelation struct {
// Metadata Whatever else is worth keeping about the relation. A creation that leaves it out stores the empty object.
// The member `pricing_adjustments` is accepted as a non-empty array of at most 64 objects with `type` (one of `discount`, `kickback`, `surcharge`, `project_discount`), `rate` (a decimal string from `0` to `1` with at most six fractional digits, never a number), `scope` (`all`, a platform, or `platform.resource_type`, in lower-case letters, digits and underscores) and an optional `description` of at most 500 characters, and no other members. The rule enforced is the schema `internal/core/adjustment/adjustments_schema.json`, which the rating engine reads the array by. An array the schema refuses is answered 422 with one field error per violation, located as `body.metadata.pricing_adjustments.<index>.<member>`.
// The stored document is bounded at 65536 bytes as the database normalizes it: a number a body spells as an exponent is stored, and answered, spelled out. A write whose document is past the bound is answered 422 and stores nothing.
Metadata *map[string]interface{} `json:"metadata,omitempty"`
// RelationType What the relation means. `infrastructure_tenant` attributes the cost of the target to the source and is the default attributing type. `member_of` groups the source under a meta-project (platform `meta`), and `managed_by` places the source under a partner (platform `partner`); neither of the two ever attributes cost. The field is a free string, so any other type is stored as it arrives.
RelationType string `json:"relation_type"`
// TargetId The project the relation reaches. It has to be registered, and it cannot be the project the relation leaves.
TargetId openapi_types.UUID `json:"target_id"`
// ValidFrom When the relation starts being valid. It defaults to the instant the relation is written.
ValidFrom *time.Time `json:"valid_from,omitempty"`
}
CreateRelation The relation to create. It leaves the project the path names, so only the other end is given here.
type DB ¶
type DB interface {
// Ping reports whether the database answers.
Ping(ctx context.Context) error
// Ready reports whether the database can serve this build's queries.
Ready(ctx context.Context) error
}
DB is the part of the database the probes need. The store satisfies it.
The two checks differ on purpose: liveness asks whether the process can reach the database at all, readiness whether this build can serve queries against it. A schema older than the build is not something restarting the pod fixes.
type DeadLetterList ¶
type DeadLetterList struct {
// Items The refused items of this page, ordered by received_at and id.
Items []DeadLetteredEvent `json:"items"`
// NextCursor Where the next page starts, passed back as `cursor`. It is null on the last page.
NextCursor *string `json:"next_cursor"`
}
DeadLetterList One page of dead-lettered events.
type DeadLetteredEvent ¶
type DeadLetteredEvent struct {
// Id The dead-letter row. A refused item has no event id this API can trust, so the row's own id is what names it.
Id openapi_types.UUID `json:"id"`
// Raw The item as it was submitted, with NUL characters scrubbed at ingest. Nothing is constrained here: what a collector sent need not be a JSON object, and this member carries whatever it was.
Raw interface{} `json:"raw"`
// Reason Why ingestion refused the item, a schema violation for example, prefixed the way the ingest response reports it.
Reason string `json:"reason"`
// ReceivedAt When this API refused the item.
ReceivedAt time.Time `json:"received_at"`
}
DeadLetteredEvent One ingest item this API refused, as the dead-letter table holds it.
type EventInput ¶
type EventInput struct {
// Cloud The installation the resource lives in, os-prod-eu1 for example. `meta` and `partner` are the clouds of the virtual projects, so an item carrying either refuses the item as well.
Cloud interface{} `json:"cloud,omitempty"`
// EventId Globally unique idempotency key of 1 to 256 characters. An event id resubmitted with the same timestamp counts as a duplicate.
EventId interface{} `json:"event_id,omitempty"`
// EventType What happened, written resource.action with an optional phase, for example compute.instance.create.end.
EventType interface{} `json:"event_type,omitempty"`
// Payload The normalized payload envelope: the state at or after the event, the full replacement size when it changed, and optional raw provider data.
Payload interface{} `json:"payload,omitempty"`
// Platform The platform the resource lives on, openstack for example. `meta` and `partner` name the two kinds of virtual project, which own no resources; an item carrying either refuses the item.
Platform interface{} `json:"platform,omitempty"`
// ProjectId The project owning the resource at or after this event.
ProjectId interface{} `json:"project_id,omitempty"`
// ResourceId The resource this event is about.
ResourceId interface{} `json:"resource_id,omitempty"`
// ResourceType The kind of resource, instance or volume for example.
ResourceType interface{} `json:"resource_type,omitempty"`
// Source Where the event came from. The stored event always reports the pipeline that ingested it, so a collector cannot mark its events as reconciliation output. The member may be left out; a value outside `collector` and `reconciliation` refuses the item.
Source interface{} `json:"source,omitempty"`
// Timestamp When the event happened, ISO 8601 with a timezone.
Timestamp interface{} `json:"timestamp,omitempty"`
AdditionalProperties map[string]interface{} `json:"-"`
}
EventInput One canonical event. The members below are described rather than constrained; the normative schema is roadmap/00-conventions.md section 4.
func (EventInput) Get ¶
func (a EventInput) Get(fieldName string) (value interface{}, found bool)
Getter for additional properties for EventInput. Returns the specified element and whether it was found
func (EventInput) MarshalJSON ¶
func (a EventInput) MarshalJSON() ([]byte, error)
Override default JSON handling for EventInput to handle AdditionalProperties
func (*EventInput) Set ¶
func (a *EventInput) Set(fieldName string, value interface{})
Setter for additional properties for EventInput
func (*EventInput) UnmarshalJSON ¶
func (a *EventInput) UnmarshalJSON(b []byte) error
Override default JSON handling for EventInput to handle AdditionalProperties
type EventList ¶
type EventList struct {
// Items The events of this page, ordered by timestamp and event id.
Items []StoredEvent `json:"items"`
// NextCursor Where the next page starts, passed back as `cursor`. It is null on the last page.
NextCursor *string `json:"next_cursor"`
}
EventList One page of stored events.
type EventStatsItem ¶
type EventStatsItem struct {
// Bucket When the bucket starts, in UTC. A bucket covers `interval` from there on, the start inclusive and the end exclusive.
Bucket time.Time `json:"bucket"`
// Cloud The installation the counted events came from.
Cloud string `json:"cloud"`
// Count How many events the group holds.
Count int64 `json:"count"`
// EventType The type the counted events carry.
EventType string `json:"event_type"`
// Source Which pipeline produced the counted events, collector or reconciliation. The member is there exactly when `group_by` names `source`.
Source *string `json:"source,omitempty"`
}
EventStatsItem One group of the event counts: the bucket it falls in, the values its dimensions carry, and how many events carry all of them.
type EventStatsList ¶
type EventStatsList struct {
// Items The groups, ordered by bucket, cloud, event type, and source. It is the empty array when the window holds no event.
Items []EventStatsItem `json:"items"`
}
EventStatsList The event counts of one window.
type GetEventStatsParams ¶
type GetEventStatsParams struct {
// GroupBy Which dimensions the counts are grouped by, as a comma-separated list. The parameter is given once: a request that repeats it, such as `group_by=cloud&group_by=event_type`, is answered 400. `cloud` and `event_type` have to be among them, because they are what an item is read by; a grouping that leaves either out is answered 400. The rule spans the members of one list, which this schema cannot express, so the handler is what enforces it.
GroupBy []GetEventStatsParamsGroupBy `form:"group_by" json:"group_by"`
// From Count only the events at or after this instant, the inclusive bound of the window.
From time.Time `form:"from" json:"from"`
// To Count only the events before this instant, the exclusive bound of the window.
To time.Time `form:"to" json:"to"`
// Interval How wide one bucket is.
Interval GetEventStatsParamsInterval `form:"interval" json:"interval"`
}
GetEventStatsParams defines parameters for GetEventStats.
type GetEventStatsParamsGroupBy ¶
type GetEventStatsParamsGroupBy string
GetEventStatsParamsGroupBy defines parameters for GetEventStats.
const ( GetEventStatsParamsGroupByCloud GetEventStatsParamsGroupBy = "cloud" GetEventStatsParamsGroupByEventType GetEventStatsParamsGroupBy = "event_type" GetEventStatsParamsGroupBySource GetEventStatsParamsGroupBy = "source" )
Defines values for GetEventStatsParamsGroupBy.
func (GetEventStatsParamsGroupBy) Valid ¶
func (e GetEventStatsParamsGroupBy) Valid() bool
Valid indicates whether the value is a known member of the GetEventStatsParamsGroupBy enum.
type GetEventStatsParamsInterval ¶
type GetEventStatsParamsInterval string
GetEventStatsParamsInterval defines parameters for GetEventStats.
const ( N1d GetEventStatsParamsInterval = "1d" N1h GetEventStatsParamsInterval = "1h" )
Defines values for GetEventStatsParamsInterval.
func (GetEventStatsParamsInterval) Valid ¶
func (e GetEventStatsParamsInterval) Valid() bool
Valid indicates whether the value is a known member of the GetEventStatsParamsInterval enum.
type GetProjectSummaryParams ¶
type GetProjectSummaryParams struct {
// From When the window starts, the inclusive bound.
From time.Time `form:"from" json:"from"`
// To When the window ends, the exclusive bound.
To time.Time `form:"to" json:"to"`
}
GetProjectSummaryParams defines parameters for GetProjectSummary.
type GetResourceStatsParams ¶
type GetResourceStatsParams struct {
// GroupBy Which dimensions the counts are grouped by, as a comma-separated list. The parameter is given once: a request that repeats it, such as `group_by=cloud&group_by=resource_type`, is answered 400. `cloud` and `resource_type` have to be among them, because they are what an item is read by; a grouping that leaves either out is answered 400. The rule spans the members of one list, which this schema cannot express, so the handler is what enforces it.
GroupBy []GetResourceStatsParamsGroupBy `form:"group_by" json:"group_by"`
// Status Which part of the fleet to count. `active` counts the rows whose state is not deleted, `deleted` counts those alone, and `all` counts both.
Status *GetResourceStatsParamsStatus `form:"status,omitempty" json:"status,omitempty"`
// At The instant the counts describe. Leaving it out asks for the current counts, which is what the projection holds.
// Any value at all is answered 501 (`urn:tally:error:not_implemented`): counting a past instant means replaying the histories, and the Phase 3 usage records are what answer that. A value meaning "now" cannot be told from a historic one, because the two differ by however long the request took, so omitting the parameter rather than sending a timestamp is how the current counts are asked for.
At *time.Time `form:"at,omitempty" json:"at,omitempty"`
}
GetResourceStatsParams defines parameters for GetResourceStats.
type GetResourceStatsParamsGroupBy ¶
type GetResourceStatsParamsGroupBy string
GetResourceStatsParamsGroupBy defines parameters for GetResourceStats.
const ( GetResourceStatsParamsGroupByCloud GetResourceStatsParamsGroupBy = "cloud" GetResourceStatsParamsGroupByPlatform GetResourceStatsParamsGroupBy = "platform" GetResourceStatsParamsGroupByProjectId GetResourceStatsParamsGroupBy = "project_id" GetResourceStatsParamsGroupByResourceType GetResourceStatsParamsGroupBy = "resource_type" GetResourceStatsParamsGroupByState GetResourceStatsParamsGroupBy = "state" )
Defines values for GetResourceStatsParamsGroupBy.
func (GetResourceStatsParamsGroupBy) Valid ¶
func (e GetResourceStatsParamsGroupBy) Valid() bool
Valid indicates whether the value is a known member of the GetResourceStatsParamsGroupBy enum.
type GetResourceStatsParamsStatus ¶
type GetResourceStatsParamsStatus string
GetResourceStatsParamsStatus defines parameters for GetResourceStats.
const ( GetResourceStatsParamsStatusActive GetResourceStatsParamsStatus = "active" GetResourceStatsParamsStatusAll GetResourceStatsParamsStatus = "all" GetResourceStatsParamsStatusDeleted GetResourceStatsParamsStatus = "deleted" )
Defines values for GetResourceStatsParamsStatus.
func (GetResourceStatsParamsStatus) Valid ¶
func (e GetResourceStatsParamsStatus) Valid() bool
Valid indicates whether the value is a known member of the GetResourceStatsParamsStatus enum.
type IngestEventsJSONBody ¶
type IngestEventsJSONBody struct {
// contains filtered or unexported fields
}
IngestEventsJSONBody defines parameters for IngestEvents.
func (IngestEventsJSONBody) AsEventInput ¶
func (t IngestEventsJSONBody) AsEventInput() (EventInput, error)
AsEventInput returns the union data inside the IngestEventsJSONBody as a EventInput
func (IngestEventsJSONBody) AsIngestEventsJSONBody1 ¶
func (t IngestEventsJSONBody) AsIngestEventsJSONBody1() (IngestEventsJSONBody1, error)
AsIngestEventsJSONBody1 returns the union data inside the IngestEventsJSONBody as a IngestEventsJSONBody1
func (*IngestEventsJSONBody) FromEventInput ¶
func (t *IngestEventsJSONBody) FromEventInput(v EventInput) error
FromEventInput overwrites any union data inside the IngestEventsJSONBody as the provided EventInput
func (*IngestEventsJSONBody) FromIngestEventsJSONBody1 ¶
func (t *IngestEventsJSONBody) FromIngestEventsJSONBody1(v IngestEventsJSONBody1) error
FromIngestEventsJSONBody1 overwrites any union data inside the IngestEventsJSONBody as the provided IngestEventsJSONBody1
func (IngestEventsJSONBody) MarshalJSON ¶
func (t IngestEventsJSONBody) MarshalJSON() ([]byte, error)
func (*IngestEventsJSONBody) MergeEventInput ¶
func (t *IngestEventsJSONBody) MergeEventInput(v EventInput) error
MergeEventInput performs a merge with any union data inside the IngestEventsJSONBody, using the provided EventInput
func (*IngestEventsJSONBody) MergeIngestEventsJSONBody1 ¶
func (t *IngestEventsJSONBody) MergeIngestEventsJSONBody1(v IngestEventsJSONBody1) error
MergeIngestEventsJSONBody1 performs a merge with any union data inside the IngestEventsJSONBody, using the provided IngestEventsJSONBody1
func (*IngestEventsJSONBody) UnmarshalJSON ¶
func (t *IngestEventsJSONBody) UnmarshalJSON(b []byte) error
type IngestEventsJSONBody1 ¶
type IngestEventsJSONBody1 = []EventInput
IngestEventsJSONBody1 defines parameters for IngestEvents.
type IngestEventsJSONRequestBody ¶
type IngestEventsJSONRequestBody IngestEventsJSONBody
IngestEventsJSONRequestBody defines body for IngestEvents for application/json ContentType.
type IngestResult ¶
type IngestResult struct {
// Accepted How many events the call stored.
Accepted int `json:"accepted"`
// Duplicates How many items the database already held.
Duplicates int `json:"duplicates"`
// Rejected The items the call refused, one entry each.
Rejected []RejectedEvent `json:"rejected"`
}
IngestResult What one ingest call did with the batch it was given.
type InvalidParamFormatError ¶
func (*InvalidParamFormatError) Error ¶
func (e *InvalidParamFormatError) Error() string
func (*InvalidParamFormatError) Unwrap ¶
func (e *InvalidParamFormatError) Unwrap() error
type Lifecycle ¶
type Lifecycle struct {
// Events The full history the fold ran on, ordered by `(timestamp, received_at, event_id)`.
Events []StoredEvent `json:"events"`
// Intervals The billable intervals the history implies, oldest first. Two billable changes at the same instant leave no interval between them, so a resource created and deleted at one instant has none at all.
Intervals []LifecycleInterval `json:"intervals"`
// Resource One resource as the projection holds it: what its event history says it is right now.
Resource Resource `json:"resource"`
// Warnings What the fold could not trust, one entry each. A history whose first event is not a create carries history_starts_without_create.
Warnings []string `json:"warnings"`
}
Lifecycle One resource, its event history, and the billable intervals that history folds into. `resource` is always there: a resource this API holds no projection row for is answered 404 rather than with an empty lifecycle.
The two halves are derived from two different event sets. `events` and `intervals` carry the history this token may read, while `resource` is the projection row, folded from every event the resource has under no scope. On a resource that changed projects the row therefore reports a `created_at` from before the reader owned it, and the first interval starts at the transfer.
type LifecycleInterval ¶
type LifecycleInterval struct {
// From When the interval starts, the inclusive bound.
From time.Time `json:"from"`
// ProjectId The project owning the resource over the interval.
ProjectId string `json:"project_id"`
// Size The size the resource had over the interval.
Size map[string]interface{} `json:"size"`
// State The state the resource was in over the interval.
State string `json:"state"`
// To When the interval ends, the exclusive bound. It is null while the interval is open, which the last interval of a living resource is.
To *time.Time `json:"to"`
}
LifecycleInterval One half-open span `[from, to)` over which nothing billable about a resource changed.
type ListEventsParams ¶
type ListEventsParams struct {
// Cloud Serve only the events of this cloud.
Cloud *string `form:"cloud,omitempty" json:"cloud,omitempty"`
// Platform Serve only the events of this platform.
Platform *string `form:"platform,omitempty" json:"platform,omitempty"`
// ProjectId Serve only the events of this project, named the way its cloud names it. A token asking for a project outside its scope is answered 403.
ProjectId *string `form:"project_id,omitempty" json:"project_id,omitempty"`
// ResourceType Serve only the events about resources of this type.
ResourceType *string `form:"resource_type,omitempty" json:"resource_type,omitempty"`
// EventType Serve only the events of this type, volume.create for example.
EventType *string `form:"event_type,omitempty" json:"event_type,omitempty"`
// Source Serve only the events the named pipeline produced.
Source *ListEventsParamsSource `form:"source,omitempty" json:"source,omitempty"`
// From Serve only the events at or after this instant, the inclusive bound of the window.
From *time.Time `form:"from,omitempty" json:"from,omitempty"`
// To Serve only the events before this instant, the exclusive bound of the window.
To *time.Time `form:"to,omitempty" json:"to,omitempty"`
// Limit How many events one page carries at most.
Limit *int `form:"limit,omitempty" json:"limit,omitempty"`
// Cursor The `next_cursor` of the page before this one. It is opaque: a client passes it back as it received it and reads nothing out of it.
Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"`
}
ListEventsParams defines parameters for ListEvents.
type ListEventsParamsSource ¶
type ListEventsParamsSource string
ListEventsParamsSource defines parameters for ListEvents.
const ( Collector ListEventsParamsSource = "collector" Reconciliation ListEventsParamsSource = "reconciliation" )
Defines values for ListEventsParamsSource.
func (ListEventsParamsSource) Valid ¶
func (e ListEventsParamsSource) Valid() bool
Valid indicates whether the value is a known member of the ListEventsParamsSource enum.
type ListProjectRelationsParams ¶
type ListProjectRelationsParams struct {
// Direction Which relations to serve: `outgoing` the ones leaving the project, `incoming` the ones reaching it, `both` either.
Direction *ListProjectRelationsParamsDirection `form:"direction,omitempty" json:"direction,omitempty"`
// RelationType Serve only the relations of this type.
RelationType *string `form:"relation_type,omitempty" json:"relation_type,omitempty"`
// At The instant the answer describes. It defaults to now.
At *time.Time `form:"at,omitempty" json:"at,omitempty"`
}
ListProjectRelationsParams defines parameters for ListProjectRelations.
type ListProjectRelationsParamsDirection ¶
type ListProjectRelationsParamsDirection string
ListProjectRelationsParamsDirection defines parameters for ListProjectRelations.
const ( Both ListProjectRelationsParamsDirection = "both" Incoming ListProjectRelationsParamsDirection = "incoming" Outgoing ListProjectRelationsParamsDirection = "outgoing" )
Defines values for ListProjectRelationsParamsDirection.
func (ListProjectRelationsParamsDirection) Valid ¶
func (e ListProjectRelationsParamsDirection) Valid() bool
Valid indicates whether the value is a known member of the ListProjectRelationsParamsDirection enum.
type ListProjectsParams ¶
type ListProjectsParams struct {
// Platform Serve only the projects of this platform.
Platform *string `form:"platform,omitempty" json:"platform,omitempty"`
// Cloud Serve only the projects of this cloud.
Cloud *string `form:"cloud,omitempty" json:"cloud,omitempty"`
// ExternalId Serve only the projects their cloud names this way. It is not a key on its own, so two clouds using the same external id are both served unless `cloud` narrows the answer.
ExternalId *string `form:"external_id,omitempty" json:"external_id,omitempty"`
// Limit How many projects one page carries at most.
Limit *int `form:"limit,omitempty" json:"limit,omitempty"`
// Cursor The `next_cursor` of the page before this one. It is opaque: a client passes it back as it received it and reads nothing out of it.
Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"`
}
ListProjectsParams defines parameters for ListProjects.
type ListRejectedEventsParams ¶
type ListRejectedEventsParams struct {
// From Serve only the items refused at or after this instant, the inclusive bound of the window.
From *time.Time `form:"from,omitempty" json:"from,omitempty"`
// To Serve only the items refused before this instant, the exclusive bound of the window.
To *time.Time `form:"to,omitempty" json:"to,omitempty"`
// Limit How many items one page carries at most.
Limit *int `form:"limit,omitempty" json:"limit,omitempty"`
// Cursor The `next_cursor` of the page before this one. It is opaque: a client passes it back as it received it and reads nothing out of it.
Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"`
}
ListRejectedEventsParams defines parameters for ListRejectedEvents.
type ListRelatedProjectsParams ¶
type ListRelatedProjectsParams struct {
// Depth How many relations out the walk goes.
Depth *int `form:"depth,omitempty" json:"depth,omitempty"`
// RelationType Walk only the relations of this type.
RelationType *string `form:"relation_type,omitempty" json:"relation_type,omitempty"`
// At The instant the answer describes. It defaults to now.
At *time.Time `form:"at,omitempty" json:"at,omitempty"`
}
ListRelatedProjectsParams defines parameters for ListRelatedProjects.
type ListResourcesParams ¶
type ListResourcesParams struct {
// Cloud Serve only the resources of this cloud.
Cloud *string `form:"cloud,omitempty" json:"cloud,omitempty"`
// Platform Serve only the resources of this platform.
Platform *string `form:"platform,omitempty" json:"platform,omitempty"`
// ProjectId Serve only the resources of this project, named the way its cloud names it. A token asking for a project outside its scope is answered 403.
ProjectId *string `form:"project_id,omitempty" json:"project_id,omitempty"`
// ResourceType Serve only the resources of this type.
ResourceType *string `form:"resource_type,omitempty" json:"resource_type,omitempty"`
// State Serve only the resources whose current state is exactly this, shutoff for example.
State *string `form:"state,omitempty" json:"state,omitempty"`
// Status Which part of the fleet to serve. `active` serves the rows whose state is not deleted, `deleted` serves those alone, and `all` serves both. `state` and `status` are independent filters, so a contradictory pair such as `state=active&status=deleted` yields the empty page.
Status *ListResourcesParamsStatus `form:"status,omitempty" json:"status,omitempty"`
// Limit How many resources one page carries at most.
Limit *int `form:"limit,omitempty" json:"limit,omitempty"`
// Cursor The `next_cursor` of the page before this one. It is opaque: a client passes it back as it received it and reads nothing out of it.
Cursor *Cursor `form:"cursor,omitempty" json:"cursor,omitempty"`
}
ListResourcesParams defines parameters for ListResources.
type ListResourcesParamsStatus ¶
type ListResourcesParamsStatus string
ListResourcesParamsStatus defines parameters for ListResources.
const ( ListResourcesParamsStatusActive ListResourcesParamsStatus = "active" ListResourcesParamsStatusAll ListResourcesParamsStatus = "all" ListResourcesParamsStatusDeleted ListResourcesParamsStatus = "deleted" )
Defines values for ListResourcesParamsStatus.
func (ListResourcesParamsStatus) Valid ¶
func (e ListResourcesParamsStatus) Valid() bool
Valid indicates whether the value is a known member of the ListResourcesParamsStatus enum.
type Options ¶
type Options struct {
// Logger is the base logger every request logger derives from. It defaults
// to the process-wide default logger.
Logger *slog.Logger
// DB is what the probes check. It is required.
DB DB
// UnhealthyThreshold is how long the database may stay unreachable before
// liveness fails and Kubernetes restarts the pod.
UnhealthyThreshold time.Duration
// Now is the clock the liveness threshold is measured on. It defaults to
// time.Now and exists so tests can control the threshold.
Now func() time.Time
// Queries is the sqlc handle the read endpoints and the ingest guard work
// through. It is bound to the pool, so the writes that need a transaction
// build their own handle instead.
Queries *sqlcgen.Queries
// Store is the database the handlers that write run their transactions on.
Store *store.Store
// AuthMode says whether the authentication middlewares check a credential
// at all.
AuthMode auth.Mode
// InternalToken is the shared secret the /internal routes are guarded with.
InternalToken string
// Authenticator resolves the bearer token of a query request into the
// principal it stands for.
Authenticator auth.Authenticator
// Pipeline ingests the batches POST /api/v1/events submits. The
// resource-type registry and the strict-mode flag travel inside it.
Pipeline *ingest.Pipeline
// AttributingRelationTypes are the relation types that attribute cost,
// which is what the cycle guard of a relation creation walks. It comes from
// TALLY_REPORTING_ATTRIBUTING_RELATION_TYPES, and an empty list disables
// the guard.
AttributingRelationTypes []string
// Syncer is the orchestrator behind POST /internal/sync/{cloud}. It is
// required: a deployment that configured no clouds passes a Syncer built
// over the empty configuration, which answers every cloud 404, so the
// handler behind the route needs no nil check.
Syncer *reconciliation.Syncer
// SyncAllowAt comes from TALLY_REPORTING_SYNC_ALLOW_AT and lets
// POST /internal/sync/{cloud} accept a request body naming the instant the
// run is at. It is off everywhere but a development deployment, where the
// cloud a sync reconciles is a simulated one.
SyncAllowAt bool
// SyncBudget comes from TALLY_REPORTING_SYNC_BUDGET_S and is how long one
// run of POST /internal/sync/{cloud} may take. A zero or negative value
// selects defaultSyncBudget.
SyncBudget time.Duration
// Metrics holds the instruments GET /metrics serves. A nil value leaves the
// route answering 404, the way a disabled scrape route does.
Metrics *metrics.Metrics
// MetricsEnabled is whether GET /metrics serves the instruments. It comes
// from the deployment's configuration, so an operator can take the scrape
// route offline without rebuilding.
MetricsEnabled bool
}
Options configures the router.
type Problem ¶
type Problem struct {
// Detail Human-readable explanation specific to this occurrence.
Detail *string `json:"detail,omitempty"`
// Errors Per-field details, set when the problem is a validation failure.
Errors *[]struct {
// Loc Location of the offending value, e.g. body.resource_id.
Loc string `json:"loc"`
// Msg What is wrong with the value at that location.
Msg string `json:"msg"`
} `json:"errors,omitempty"`
// Status The HTTP status code of this response.
//
// Example: 400
Status int `json:"status"`
// Title Short human-readable summary of the problem type.
//
// Example: Validation failed
Title string `json:"title"`
// Type URI reference identifying the problem type.
//
// Example: urn:tally:error:validation
Type string `json:"type"`
}
Problem RFC 9457 problem detail. Every error response in this API uses this shape, served as application/problem+json.
type Project ¶
type Project struct {
// Cloud The installation the project lives in, os-prod-eu1 for example. A virtual project carries its platform here, and no real project carries `meta` or `partner`.
Cloud string `json:"cloud"`
// CreatedAt When the project was registered.
CreatedAt time.Time `json:"created_at"`
// ExternalId The project as its cloud names it, which is the id an event carries.
ExternalId string `json:"external_id"`
// Id The project, as this API names it.
Id openapi_types.UUID `json:"id"`
// Metadata Whatever else was stored about the project. It is the empty object for a project registered without any.
Metadata map[string]interface{} `json:"metadata"`
// Name What the project is called, null for a project registered without a name.
Name *string `json:"name"`
// Platform The platform the project lives on, openstack for example. `meta` and `partner` are reserved for the two kinds of virtual project that own no resources: the meta-project and the partner.
Platform string `json:"platform"`
}
Project One registered project. The registry is keyed by `(cloud, external_id)`, and `id` is what the other operations address the project by.
type ProjectActivity ¶
type ProjectActivity struct {
// ActiveNow How many resources of the type the project holds right now, counted off the projection rows that are not deleted. It describes the present rather than the window, so a type the window saw nothing of still reports what the project runs of it today.
ActiveNow int `json:"active_now"`
// Created How many resources of the type began their life inside the window.
Created int `json:"created"`
// Deleted How many resources of the type ended their life inside the window.
Deleted int `json:"deleted"`
// ResourceType The kind of resource this row is about.
ResourceType string `json:"resource_type"`
// TotalMinutes How long the resources of the type ran inside the window, in whole minutes, truncated. An interval still open is counted up to the instant of the request, so a window reaching into the future carries no time that has not been served yet.
TotalMinutes int64 `json:"total_minutes"`
}
ProjectActivity What one resource type of a project did inside the window of a summary.
type ProjectList ¶
type ProjectList struct {
// Items The projects of this page, ordered by cloud and external id.
Items []Project `json:"items"`
// NextCursor Where the next page starts, passed back as `cursor`. It is null on the last page.
NextCursor *string `json:"next_cursor"`
}
ProjectList One page of registered projects.
type ProjectRef ¶
type ProjectRef struct {
// Cloud The installation the project lives in, os-prod-eu1 for example.
Cloud string `json:"cloud"`
// ExternalId The project as its cloud names it, which is the id an event carries.
ExternalId string `json:"external_id"`
// Id The project, as this API names it.
Id openapi_types.UUID `json:"id"`
}
ProjectRef Which project an answer is about, as much of it as a project-scoped read carries. The registry row itself — the name, the operator-set metadata, the platform, and when it was registered — is what `getProject` serves, and reading that takes `read_all`.
type ProjectSummary ¶
type ProjectSummary struct {
// Project Which project an answer is about, as much of it as a project-scoped read carries. The registry row itself — the name, the operator-set metadata, the platform, and when it was registered — is what `getProject` serves, and reading that takes `read_all`.
Project ProjectRef `json:"project"`
// ResourceTypes One row per resource type the project has events or resources of, ordered by resource type. It is the empty array for a project with neither.
ResourceTypes []ProjectActivity `json:"resource_types"`
}
ProjectSummary One project and what its resource types did inside one window.
type PutResourceTypeJSONRequestBody ¶
type PutResourceTypeJSONRequestBody = RegisterResourceType
PutResourceTypeJSONRequestBody defines body for PutResourceType for application/json ContentType.
type RebuildProjectionJSONRequestBody ¶
type RebuildProjectionJSONRequestBody = RebuildRequest
RebuildProjectionJSONRequestBody defines body for RebuildProjection for application/json ContentType.
type RebuildRequest ¶
type RebuildRequest struct {
// Cloud Replay only the resources of this cloud.
Cloud *string `json:"cloud,omitempty"`
// ResourceType Replay only the resources of this type.
ResourceType *string `json:"resource_type,omitempty"`
}
RebuildRequest Which resources to replay. A member left out filters nothing, so an empty object rebuilds every resource the events table knows.
type RebuildResult ¶
type RebuildResult struct {
// Rebuilt How many resources were replayed.
Rebuilt int `json:"rebuilt"`
}
RebuildResult What one rebuild replayed.
type RegisterResourceType ¶
type RegisterResourceType struct {
// SizeSchema A JSON Schema draft 2020-12 document. It is compiled before it is stored, so the document a registration accepts is exactly the one ingestion can apply later.
SizeSchema map[string]interface{} `json:"size_schema"`
}
RegisterResourceType The size schema to register for a resource type.
type RejectedEvent ¶
type RejectedEvent struct {
// EventId The event id the item carried. It is the empty string for an item that carried none, which is why the index is what identifies the item.
EventId string `json:"event_id"`
// Index The item's position in the submitted batch, counted from zero.
Index int `json:"index"`
// Reason Why the item was refused, for example "size_schema: 'vcpus' is a required property" or 'schema: platform: "meta" is a virtual platform, which never carries resources'.
Reason string `json:"reason"`
}
RejectedEvent One refused item and the reason it was refused.
type RelatedProject ¶
type RelatedProject struct {
// Depth How many relations lie between the project the walk started from and this one.
Depth int `json:"depth"`
// Path The relation ids from the start to this project in walk order, so it holds `depth` of them.
Path []openapi_types.UUID `json:"path"`
// Project One registered project. The registry is keyed by `(cloud, external_id)`, and `id` is what the other operations address the project by.
Project Project `json:"project"`
// RelationType The type of the relation the walk arrived on.
RelationType string `json:"relation_type"`
}
RelatedProject One project a traversal reached.
type RelatedProjectList ¶
type RelatedProjectList struct {
// Items The projects the walk reached, in the order it visited them.
Items []RelatedProject `json:"items"`
}
RelatedProjectList The projects one traversal reached.
type Relation ¶
type Relation struct {
// CreatedAt When the relation was written.
CreatedAt time.Time `json:"created_at"`
// Id The relation, as this API names it.
Id openapi_types.UUID `json:"id"`
// Metadata Whatever else was stored about the relation. It is the empty object for a relation created without any.
// The member `pricing_adjustments`, when present, holds a non-empty array of at most 64 objects with `type` (one of `discount`, `kickback`, `surcharge`, `project_discount`), `rate` (a decimal string from `0` to `1` with at most six fractional digits, never a number), `scope` (`all`, a platform, or `platform.resource_type`, in lower-case letters, digits and underscores) and an optional `description` of at most 500 characters, and no other members. The schema `internal/core/adjustment/adjustments_schema.json` decided the array at the write, and the rating engine reads it by that same schema.
Metadata map[string]interface{} `json:"metadata"`
// RelationType What the relation means. `infrastructure_tenant` attributes the cost of the target to the source and is the default attributing type. `member_of` groups the source under a meta-project (platform `meta`), and `managed_by` places the source under a partner (platform `partner`); neither of the two ever attributes cost. The field is a free string, so any other type is stored as it arrives.
RelationType string `json:"relation_type"`
// SourceId The project the relation leaves.
SourceId openapi_types.UUID `json:"source_id"`
// TargetId The project the relation reaches.
TargetId openapi_types.UUID `json:"target_id"`
// ValidFrom When the relation starts being valid, the inclusive bound.
ValidFrom time.Time `json:"valid_from"`
// ValidTo When the relation stops being valid, the exclusive bound. It is null while the relation is open.
ValidTo *time.Time `json:"valid_to"`
}
Relation One relation between two projects. It is valid at `t` iff `valid_from <= t AND (valid_to IS NULL OR valid_to > t)`, and it is closed rather than deleted, so a read at an earlier instant still finds it.
type RelationList ¶
type RelationList struct {
// Items The relations valid at that instant, ordered by created_at and id.
Items []Relation `json:"items"`
}
RelationList The relations of one project at one instant.
type RequiredHeaderError ¶
func (*RequiredHeaderError) Error ¶
func (e *RequiredHeaderError) Error() string
func (*RequiredHeaderError) Unwrap ¶
func (e *RequiredHeaderError) Unwrap() error
type RequiredParamError ¶
type RequiredParamError struct {
ParamName string
}
func (*RequiredParamError) Error ¶
func (e *RequiredParamError) Error() string
type Resource ¶
type Resource struct {
// Cloud The installation the resource lives in.
Cloud string `json:"cloud"`
// CreatedAt When the resource was created, as the projection folded it from the resource's whole history. It is null for a history that never showed a create. The projection is not scoped to the reading token, so on a resource that changed projects this is the create of the project it came from and predates the reader's ownership: what a project is billed for is the lifecycle's `intervals`, never `created_at` paired with `deleted_at`.
CreatedAt *time.Time `json:"created_at"`
// DeletedAt When the resource was deleted, null while it lives.
DeletedAt *time.Time `json:"deleted_at"`
// FirstEventAt When the earliest event folded into this row happened. Every row carries it, so it answers for a resource whose history opens with something other than a create and leaves `created_at` null; where the history does open with a create the two hold the same instant. It is unscoped the way `created_at` is, so on a resource that changed projects it is the first event of the project it came from and predates the reader's ownership. It says when the resource entered the record, not what anyone owes: what a project is billed for is the lifecycle's `intervals`.
FirstEventAt time.Time `json:"first_event_at"`
// LastEventAt When that event happened.
LastEventAt time.Time `json:"last_event_at"`
// LastEventType The type of the newest event folded into this row. It is a `sync.create`, `sync.update`, or `sync.delete` when the newest thing that happened to the resource was a correction by the reconciliation framework rather than a report by a collector.
LastEventType string `json:"last_event_type"`
// LastPayload The payload envelope of that event, member for member as it was stored, and null for a row that holds none.
LastPayload *map[string]interface{} `json:"last_payload"`
// Platform The platform the resource lives on.
Platform string `json:"platform"`
// ProjectId The project owning the resource now.
ProjectId string `json:"project_id"`
// ResourceId The resource itself, as its cloud names it.
ResourceId string `json:"resource_id"`
// ResourceType The kind of resource.
ResourceType string `json:"resource_type"`
// Size The size the resource has now, member for member as its events reported it. It is the empty object for a history that reported no size.
Size map[string]interface{} `json:"size"`
// State The state the resource is in now. A deleted resource carries deleted, which the server sets itself rather than reading it off the delete event.
State string `json:"state"`
}
Resource One resource as the projection holds it: what its event history says it is right now.
type ResourceList ¶
type ResourceList struct {
// Items The resources of this page, ordered by cloud, resource type, and resource id.
Items []Resource `json:"items"`
// NextCursor Where the next page starts, passed back as `cursor`. It is null on the last page.
NextCursor *string `json:"next_cursor"`
}
ResourceList One page of current resources.
type ResourceStatsItem ¶
type ResourceStatsItem struct {
// Cloud The installation the counted resources live in.
Cloud string `json:"cloud"`
// Count How many resources the group holds.
Count int64 `json:"count"`
// Platform The platform the counted resources live on. The member is there exactly when `group_by` names `platform`.
Platform *string `json:"platform,omitempty"`
// ProjectId The project owning the counted resources, named the way its cloud names it. The member is there exactly when `group_by` names `project_id`.
ProjectId *string `json:"project_id,omitempty"`
// ResourceType The kind of resource that was counted.
ResourceType string `json:"resource_type"`
// State The state the counted resources are in. The member is there exactly when `group_by` names `state`.
State *string `json:"state,omitempty"`
}
ResourceStatsItem One group of the resource counts: the values its dimensions carry, and how many resources carry all of them.
type ResourceStatsList ¶
type ResourceStatsList struct {
// Items The groups, ordered by cloud, resource type, state, platform, and project id. It is the empty array when the grouping counts no resource at all.
Items []ResourceStatsItem `json:"items"`
}
ResourceStatsList The resource counts of one grouping.
type ResourceType ¶
type ResourceType struct {
// Platform The platform the resource type belongs to.
Platform string `json:"platform"`
// ResourceType The resource type within that platform.
ResourceType string `json:"resource_type"`
// SizeSchema The registered JSON Schema draft 2020-12 document.
SizeSchema map[string]interface{} `json:"size_schema"`
// UpdatedAt When the schema was last written.
UpdatedAt time.Time `json:"updated_at"`
}
ResourceType One registered resource type and the size schema the sizes reported for it are validated against.
type ResourceTypeList ¶
type ResourceTypeList struct {
// Items The resource types, ordered by platform and resource type.
Items []ResourceType `json:"items"`
// NextCursor Where the next page starts. It is always null today: the registry holds one row per resource type, so every registration fits into one answer. The registry list stays a single page, while the query lists page with cursors.
NextCursor *string `json:"next_cursor"`
}
ResourceTypeList The registered resource types.
type ServerInterface ¶
type ServerInterface interface {
// ListEvents List stored events
// (GET /api/v1/events)
ListEvents(w http.ResponseWriter, r *http.Request, params ListEventsParams)
// IngestEvents Ingest events
// (POST /api/v1/events)
IngestEvents(w http.ResponseWriter, r *http.Request)
// ListProjects List the registered projects
// (GET /api/v1/projects)
ListProjects(w http.ResponseWriter, r *http.Request, params ListProjectsParams)
// CreateProject Register a project
// (POST /api/v1/projects)
CreateProject(w http.ResponseWriter, r *http.Request)
// GetProject Read one registered project
// (GET /api/v1/projects/{id})
GetProject(w http.ResponseWriter, r *http.Request, id Uuid)
// UpdateProject Update one registered project
// (PATCH /api/v1/projects/{id})
UpdateProject(w http.ResponseWriter, r *http.Request, id Uuid)
// ListRelatedProjects List the projects one project reaches
// (GET /api/v1/projects/{id}/related)
ListRelatedProjects(w http.ResponseWriter, r *http.Request, id Uuid, params ListRelatedProjectsParams)
// ListProjectRelations List the relations of one project
// (GET /api/v1/projects/{id}/relations)
ListProjectRelations(w http.ResponseWriter, r *http.Request, id Uuid, params ListProjectRelationsParams)
// CreateProjectRelation Relate one project to another
// (POST /api/v1/projects/{id}/relations)
CreateProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid)
// DeleteProjectRelation Close one relation
// (DELETE /api/v1/projects/{id}/relations/{relation_id})
DeleteProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid, relationId Uuid)
// UpdateProjectRelation Update one relation
// (PATCH /api/v1/projects/{id}/relations/{relation_id})
UpdateProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid, relationId Uuid)
// GetProjectSummary Summarize what one project ran inside a window
// (GET /api/v1/projects/{id}/summary)
GetProjectSummary(w http.ResponseWriter, r *http.Request, id Uuid, params GetProjectSummaryParams)
// ListRejectedEvents List the dead-lettered events
// (GET /api/v1/rejected-events)
ListRejectedEvents(w http.ResponseWriter, r *http.Request, params ListRejectedEventsParams)
// ListResourceTypes List the registered resource types
// (GET /api/v1/resource-types)
ListResourceTypes(w http.ResponseWriter, r *http.Request)
// GetResourceType Read one registered resource type
// (GET /api/v1/resource-types/{platform}/{resource_type})
GetResourceType(w http.ResponseWriter, r *http.Request, platform string, resourceType string)
// PutResourceType Register a resource type
// (PUT /api/v1/resource-types/{platform}/{resource_type})
PutResourceType(w http.ResponseWriter, r *http.Request, platform string, resourceType string)
// ListResources List the current resources
// (GET /api/v1/resources)
ListResources(w http.ResponseWriter, r *http.Request, params ListResourcesParams)
// ListResourceEvents Read the event history of one resource
// (GET /api/v1/resources/{cloud}/{resource_type}/{resource_id}/events)
ListResourceEvents(w http.ResponseWriter, r *http.Request, cloud string, resourceType string, resourceId string)
// GetResourceLifecycle Read the folded lifecycle of one resource
// (GET /api/v1/resources/{cloud}/{resource_type}/{resource_id}/lifecycle)
GetResourceLifecycle(w http.ResponseWriter, r *http.Request, cloud string, resourceType string, resourceId string)
// GetEventStats Count the stored events per time bucket
// (GET /api/v1/stats/events)
GetEventStats(w http.ResponseWriter, r *http.Request, params GetEventStatsParams)
// GetResourceStats Count the current resources per group
// (GET /api/v1/stats/resources)
GetResourceStats(w http.ResponseWriter, r *http.Request, params GetResourceStatsParams)
// Healthz Liveness probe
// (GET /healthz)
Healthz(w http.ResponseWriter, r *http.Request)
// RebuildProjection Rebuild the projection
// (POST /internal/projection/rebuild)
RebuildProjection(w http.ResponseWriter, r *http.Request)
// SyncCloud Reconcile one cloud
// (POST /internal/sync/{cloud})
SyncCloud(w http.ResponseWriter, r *http.Request, cloud string)
// Metrics Service metrics
// (GET /metrics)
Metrics(w http.ResponseWriter, r *http.Request)
// Readyz Readiness probe
// (GET /readyz)
Readyz(w http.ResponseWriter, r *http.Request)
}
ServerInterface represents all server handlers.
type ServerInterfaceWrapper ¶
type ServerInterfaceWrapper struct {
Handler ServerInterface
HandlerMiddlewares []MiddlewareFunc
ErrorHandlerFunc func(w http.ResponseWriter, r *http.Request, err error)
}
ServerInterfaceWrapper converts contexts to parameters.
func (*ServerInterfaceWrapper) CreateProject ¶
func (siw *ServerInterfaceWrapper) CreateProject(w http.ResponseWriter, r *http.Request)
CreateProject operation middleware
func (*ServerInterfaceWrapper) CreateProjectRelation ¶
func (siw *ServerInterfaceWrapper) CreateProjectRelation(w http.ResponseWriter, r *http.Request)
CreateProjectRelation operation middleware
func (*ServerInterfaceWrapper) DeleteProjectRelation ¶
func (siw *ServerInterfaceWrapper) DeleteProjectRelation(w http.ResponseWriter, r *http.Request)
DeleteProjectRelation operation middleware
func (*ServerInterfaceWrapper) GetEventStats ¶
func (siw *ServerInterfaceWrapper) GetEventStats(w http.ResponseWriter, r *http.Request)
GetEventStats operation middleware
func (*ServerInterfaceWrapper) GetProject ¶
func (siw *ServerInterfaceWrapper) GetProject(w http.ResponseWriter, r *http.Request)
GetProject operation middleware
func (*ServerInterfaceWrapper) GetProjectSummary ¶
func (siw *ServerInterfaceWrapper) GetProjectSummary(w http.ResponseWriter, r *http.Request)
GetProjectSummary operation middleware
func (*ServerInterfaceWrapper) GetResourceLifecycle ¶
func (siw *ServerInterfaceWrapper) GetResourceLifecycle(w http.ResponseWriter, r *http.Request)
GetResourceLifecycle operation middleware
func (*ServerInterfaceWrapper) GetResourceStats ¶
func (siw *ServerInterfaceWrapper) GetResourceStats(w http.ResponseWriter, r *http.Request)
GetResourceStats operation middleware
func (*ServerInterfaceWrapper) GetResourceType ¶
func (siw *ServerInterfaceWrapper) GetResourceType(w http.ResponseWriter, r *http.Request)
GetResourceType operation middleware
func (*ServerInterfaceWrapper) Healthz ¶
func (siw *ServerInterfaceWrapper) Healthz(w http.ResponseWriter, r *http.Request)
Healthz operation middleware
func (*ServerInterfaceWrapper) IngestEvents ¶
func (siw *ServerInterfaceWrapper) IngestEvents(w http.ResponseWriter, r *http.Request)
IngestEvents operation middleware
func (*ServerInterfaceWrapper) ListEvents ¶
func (siw *ServerInterfaceWrapper) ListEvents(w http.ResponseWriter, r *http.Request)
ListEvents operation middleware
func (*ServerInterfaceWrapper) ListProjectRelations ¶
func (siw *ServerInterfaceWrapper) ListProjectRelations(w http.ResponseWriter, r *http.Request)
ListProjectRelations operation middleware
func (*ServerInterfaceWrapper) ListProjects ¶
func (siw *ServerInterfaceWrapper) ListProjects(w http.ResponseWriter, r *http.Request)
ListProjects operation middleware
func (*ServerInterfaceWrapper) ListRejectedEvents ¶
func (siw *ServerInterfaceWrapper) ListRejectedEvents(w http.ResponseWriter, r *http.Request)
ListRejectedEvents operation middleware
func (*ServerInterfaceWrapper) ListRelatedProjects ¶
func (siw *ServerInterfaceWrapper) ListRelatedProjects(w http.ResponseWriter, r *http.Request)
ListRelatedProjects operation middleware
func (*ServerInterfaceWrapper) ListResourceEvents ¶
func (siw *ServerInterfaceWrapper) ListResourceEvents(w http.ResponseWriter, r *http.Request)
ListResourceEvents operation middleware
func (*ServerInterfaceWrapper) ListResourceTypes ¶
func (siw *ServerInterfaceWrapper) ListResourceTypes(w http.ResponseWriter, r *http.Request)
ListResourceTypes operation middleware
func (*ServerInterfaceWrapper) ListResources ¶
func (siw *ServerInterfaceWrapper) ListResources(w http.ResponseWriter, r *http.Request)
ListResources operation middleware
func (*ServerInterfaceWrapper) Metrics ¶
func (siw *ServerInterfaceWrapper) Metrics(w http.ResponseWriter, r *http.Request)
Metrics operation middleware
func (*ServerInterfaceWrapper) PutResourceType ¶
func (siw *ServerInterfaceWrapper) PutResourceType(w http.ResponseWriter, r *http.Request)
PutResourceType operation middleware
func (*ServerInterfaceWrapper) Readyz ¶
func (siw *ServerInterfaceWrapper) Readyz(w http.ResponseWriter, r *http.Request)
Readyz operation middleware
func (*ServerInterfaceWrapper) RebuildProjection ¶
func (siw *ServerInterfaceWrapper) RebuildProjection(w http.ResponseWriter, r *http.Request)
RebuildProjection operation middleware
func (*ServerInterfaceWrapper) SyncCloud ¶
func (siw *ServerInterfaceWrapper) SyncCloud(w http.ResponseWriter, r *http.Request)
SyncCloud operation middleware
func (*ServerInterfaceWrapper) UpdateProject ¶
func (siw *ServerInterfaceWrapper) UpdateProject(w http.ResponseWriter, r *http.Request)
UpdateProject operation middleware
func (*ServerInterfaceWrapper) UpdateProjectRelation ¶
func (siw *ServerInterfaceWrapper) UpdateProjectRelation(w http.ResponseWriter, r *http.Request)
UpdateProjectRelation operation middleware
type StoredEvent ¶
type StoredEvent struct {
// Cloud The installation the resource lives in.
Cloud string `json:"cloud"`
// EventId The idempotency key the event was submitted under.
EventId string `json:"event_id"`
// EventType What happened, written resource.action with an optional phase, for example compute.instance.create.end. The reconciliation framework writes the second family, `sync.create`, `sync.update`, and `sync.delete`: a correction is about no one service, so it names none. `source` is the member to branch on rather than the prefix — it is `reconciliation` for exactly those events.
EventType string `json:"event_type"`
// Payload The normalized payload envelope, member for member as it was stored. It is null for an event stored without one, which a delete event may be. The members are not constrained here: an envelope keeps the fields a provider sent beyond the ones this API names.
Payload *map[string]interface{} `json:"payload"`
// Platform The platform the resource lives on.
Platform string `json:"platform"`
// ProjectId The project owning the resource at or after this event.
ProjectId string `json:"project_id"`
// ReceivedAt When this API stored the event.
ReceivedAt time.Time `json:"received_at"`
// ResourceId The resource the event is about.
ResourceId string `json:"resource_id"`
// ResourceType The kind of resource the event is about.
ResourceType string `json:"resource_type"`
// Source Which pipeline produced the event, collector or reconciliation. It is what the server recorded rather than what the submitter claimed.
Source string `json:"source"`
// Timestamp When the event happened.
Timestamp time.Time `json:"timestamp"`
}
StoredEvent One event as the events table holds it: what was submitted, plus the instant this API stored it.
type SyncCloudJSONRequestBody ¶
type SyncCloudJSONRequestBody = SyncRequest
SyncCloudJSONRequestBody defines body for SyncCloud for application/json ContentType.
type SyncRequest ¶
type SyncRequest struct {
// At Run the sync at this instant instead of at wall time: the run's `sync_runs` row starts here, and every correction the run books carries this timestamp. The deployment has to set `TALLY_REPORTING_SYNC_ALLOW_AT` for the member to be accepted. It exists for a development deployment reconciling a simulated cloud, whose clock is not the wall clock.
At *time.Time `json:"at,omitempty"`
}
SyncRequest When the run happens. The member is optional, and a request that leaves it out, like one that carries no body at all, syncs at wall time.
type SyncResult ¶
type SyncResult struct {
// Stats The tally of one sync run, which is one that finished clean.
Stats SyncStats `json:"stats"`
// SyncRunId The id of the `sync_runs` row this run wrote. It is what an operator reads the run back by, and what the synthetic event ids of the run are derived from.
SyncRunId string `json:"sync_run_id"`
}
SyncResult What one sync run did.
type SyncStats ¶
type SyncStats struct {
// Created How many resources the run reported to the projection as new, one synthetic event each.
Created int `json:"created"`
// Deleted How many it reported as gone.
Deleted int `json:"deleted"`
// Updated How many it corrected the state, size, or owner of.
Updated int `json:"updated"`
}
SyncStats The tally of one sync run, which is one that finished clean.
type TooManyValuesForParamError ¶
func (*TooManyValuesForParamError) Error ¶
func (e *TooManyValuesForParamError) Error() string
type UnescapedCookieParamError ¶
func (*UnescapedCookieParamError) Error ¶
func (e *UnescapedCookieParamError) Error() string
func (*UnescapedCookieParamError) Unwrap ¶
func (e *UnescapedCookieParamError) Unwrap() error
type Unimplemented ¶
type Unimplemented struct{}
func (Unimplemented) CreateProject ¶
func (_ Unimplemented) CreateProject(w http.ResponseWriter, r *http.Request)
CreateProject Register a project (POST /api/v1/projects)
func (Unimplemented) CreateProjectRelation ¶
func (_ Unimplemented) CreateProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid)
CreateProjectRelation Relate one project to another (POST /api/v1/projects/{id}/relations)
func (Unimplemented) DeleteProjectRelation ¶
func (_ Unimplemented) DeleteProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid, relationId Uuid)
DeleteProjectRelation Close one relation (DELETE /api/v1/projects/{id}/relations/{relation_id})
func (Unimplemented) GetEventStats ¶
func (_ Unimplemented) GetEventStats(w http.ResponseWriter, r *http.Request, params GetEventStatsParams)
GetEventStats Count the stored events per time bucket (GET /api/v1/stats/events)
func (Unimplemented) GetProject ¶
func (_ Unimplemented) GetProject(w http.ResponseWriter, r *http.Request, id Uuid)
GetProject Read one registered project (GET /api/v1/projects/{id})
func (Unimplemented) GetProjectSummary ¶
func (_ Unimplemented) GetProjectSummary(w http.ResponseWriter, r *http.Request, id Uuid, params GetProjectSummaryParams)
GetProjectSummary Summarize what one project ran inside a window (GET /api/v1/projects/{id}/summary)
func (Unimplemented) GetResourceLifecycle ¶
func (_ Unimplemented) GetResourceLifecycle(w http.ResponseWriter, r *http.Request, cloud string, resourceType string, resourceId string)
GetResourceLifecycle Read the folded lifecycle of one resource (GET /api/v1/resources/{cloud}/{resource_type}/{resource_id}/lifecycle)
func (Unimplemented) GetResourceStats ¶
func (_ Unimplemented) GetResourceStats(w http.ResponseWriter, r *http.Request, params GetResourceStatsParams)
GetResourceStats Count the current resources per group (GET /api/v1/stats/resources)
func (Unimplemented) GetResourceType ¶
func (_ Unimplemented) GetResourceType(w http.ResponseWriter, r *http.Request, platform string, resourceType string)
GetResourceType Read one registered resource type (GET /api/v1/resource-types/{platform}/{resource_type})
func (Unimplemented) Healthz ¶
func (_ Unimplemented) Healthz(w http.ResponseWriter, r *http.Request)
Healthz Liveness probe (GET /healthz)
func (Unimplemented) IngestEvents ¶
func (_ Unimplemented) IngestEvents(w http.ResponseWriter, r *http.Request)
IngestEvents Ingest events (POST /api/v1/events)
func (Unimplemented) ListEvents ¶
func (_ Unimplemented) ListEvents(w http.ResponseWriter, r *http.Request, params ListEventsParams)
ListEvents List stored events (GET /api/v1/events)
func (Unimplemented) ListProjectRelations ¶
func (_ Unimplemented) ListProjectRelations(w http.ResponseWriter, r *http.Request, id Uuid, params ListProjectRelationsParams)
ListProjectRelations List the relations of one project (GET /api/v1/projects/{id}/relations)
func (Unimplemented) ListProjects ¶
func (_ Unimplemented) ListProjects(w http.ResponseWriter, r *http.Request, params ListProjectsParams)
ListProjects List the registered projects (GET /api/v1/projects)
func (Unimplemented) ListRejectedEvents ¶
func (_ Unimplemented) ListRejectedEvents(w http.ResponseWriter, r *http.Request, params ListRejectedEventsParams)
ListRejectedEvents List the dead-lettered events (GET /api/v1/rejected-events)
func (Unimplemented) ListRelatedProjects ¶
func (_ Unimplemented) ListRelatedProjects(w http.ResponseWriter, r *http.Request, id Uuid, params ListRelatedProjectsParams)
ListRelatedProjects List the projects one project reaches (GET /api/v1/projects/{id}/related)
func (Unimplemented) ListResourceEvents ¶
func (_ Unimplemented) ListResourceEvents(w http.ResponseWriter, r *http.Request, cloud string, resourceType string, resourceId string)
ListResourceEvents Read the event history of one resource (GET /api/v1/resources/{cloud}/{resource_type}/{resource_id}/events)
func (Unimplemented) ListResourceTypes ¶
func (_ Unimplemented) ListResourceTypes(w http.ResponseWriter, r *http.Request)
ListResourceTypes List the registered resource types (GET /api/v1/resource-types)
func (Unimplemented) ListResources ¶
func (_ Unimplemented) ListResources(w http.ResponseWriter, r *http.Request, params ListResourcesParams)
ListResources List the current resources (GET /api/v1/resources)
func (Unimplemented) Metrics ¶
func (_ Unimplemented) Metrics(w http.ResponseWriter, r *http.Request)
Metrics Service metrics (GET /metrics)
func (Unimplemented) PutResourceType ¶
func (_ Unimplemented) PutResourceType(w http.ResponseWriter, r *http.Request, platform string, resourceType string)
PutResourceType Register a resource type (PUT /api/v1/resource-types/{platform}/{resource_type})
func (Unimplemented) Readyz ¶
func (_ Unimplemented) Readyz(w http.ResponseWriter, r *http.Request)
Readyz Readiness probe (GET /readyz)
func (Unimplemented) RebuildProjection ¶
func (_ Unimplemented) RebuildProjection(w http.ResponseWriter, r *http.Request)
RebuildProjection Rebuild the projection (POST /internal/projection/rebuild)
func (Unimplemented) SyncCloud ¶
func (_ Unimplemented) SyncCloud(w http.ResponseWriter, r *http.Request, cloud string)
SyncCloud Reconcile one cloud (POST /internal/sync/{cloud})
func (Unimplemented) UpdateProject ¶
func (_ Unimplemented) UpdateProject(w http.ResponseWriter, r *http.Request, id Uuid)
UpdateProject Update one registered project (PATCH /api/v1/projects/{id})
func (Unimplemented) UpdateProjectRelation ¶
func (_ Unimplemented) UpdateProjectRelation(w http.ResponseWriter, r *http.Request, id Uuid, relationId Uuid)
UpdateProjectRelation Update one relation (PATCH /api/v1/projects/{id}/relations/{relation_id})
type UnmarshalingParamError ¶
func (*UnmarshalingParamError) Error ¶
func (e *UnmarshalingParamError) Error() string
func (*UnmarshalingParamError) Unwrap ¶
func (e *UnmarshalingParamError) Unwrap() error
type UpdateProject ¶
type UpdateProject struct {
// Metadata The metadata the project carries from now on. It replaces the stored object wholesale rather than being merged into it, so a request carrying it carries every member the project keeps.
// The stored document is bounded at 65536 bytes as the database normalizes it: a number a body spells as an exponent is stored, and answered, spelled out. A write whose document is past the bound is answered 422 and stores nothing.
Metadata *map[string]interface{} `json:"metadata,omitempty"`
// Name What the project is called from now on.
Name *string `json:"name,omitempty"`
}
UpdateProject What to change about a project. A member the request leaves out stays as it is, so at least one of them has to be present.
type UpdateProjectJSONRequestBody ¶
type UpdateProjectJSONRequestBody = UpdateProject
UpdateProjectJSONRequestBody defines body for UpdateProject for application/json ContentType.
type UpdateProjectRelationJSONRequestBody ¶
type UpdateProjectRelationJSONRequestBody = UpdateRelation
UpdateProjectRelationJSONRequestBody defines body for UpdateProjectRelation for application/json ContentType.
type UpdateRelation ¶
type UpdateRelation struct {
// Metadata The metadata the relation carries from now on. It replaces the stored object wholesale rather than being merged into it, so a request carrying it carries every member the relation keeps.
// The `pricing_adjustments` of a relation are fixed for its lifetime. A document whose member differs from the stored one, by being added, dropped, reordered or changed in any value, is answered 409. To change the other members, send the member back exactly as the relation answers it; to change the adjustments, close the relation and create a successor.
// The stored document is bounded at 65536 bytes as the database normalizes it: a number a body spells as an exponent is stored, and answered, spelled out. A write whose document is past the bound is answered 422 and stores nothing.
Metadata *map[string]interface{} `json:"metadata,omitempty"`
// ValidTo When the relation stops being valid. It has to be after `valid_from`. The member is not nullable: an open relation is closed here and a closed one gets its close instant corrected, while reopening a closed relation is not supported.
ValidTo *time.Time `json:"valid_to,omitempty"`
}
UpdateRelation What to change about a relation. A member the request leaves out stays as it is, so at least one of them has to be present.