mirror of
https://github.com/SigNoz/signoz.git
synced 2026-06-20 23:30:31 +01:00
issue_5267
9 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
58b55c922d |
fix(openapi): omit content type for responses without a body (#11720)
Some checks failed
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
ServeOpenAPI's nil-response branch still passed WithContentType, so any route
with Response == nil but a ResponseContentType set (notably 204 No Content)
emitted a content block in the generated spec. Clients then try to decode an
empty body and fail — e.g. "unexpected end of JSON input" on
DELETE /api/v1/service_accounts/{id}.
Omit the content type when Response is nil. Regenerate docs/api/openapi.yml (18
bodyless responses drop their content block) and the frontend orval client.
Signed-off-by: grandwizard28 <vibhupandey28@gmail.com>
|
||
|
|
36334309bb |
feat(resource): add resource middleware (#11607)
* feat(resource): initial commit
* feat(resource): add related resources
* feat(resource): audit cleanup
* refactor(resource): set audit category on resource defs; drop MustNew/validate
- Set Category (access_control) on every service account and role ResourceDef
so audit events carry signoz.audit.action_category
- Remove MustNewResourceDef/MustNewResourcesDef and validate(); registration
via plain ResourceDef literals again. Validation to be revisited separately
* feat(audit): emit audit events only for mutating verbs
- Add coretypes.Verb.IsMutation() (create/update/delete/attach/detach)
- Audit skips read/list defs (they remain for authz); failed and denied
mutations still emit with Outcome=failure
* feat(audit): mirror attach/detach audit on both ends for role↔service account
Role def on SetRole/DeleteRole now carries Related=ServiceAccount so each
permission-checked end emits its own event (serviceaccount.attached to role
and role.attached to serviceaccount), matching the both-ends authz model.
* refactor(resource): co-locate resolved context in handler; slice-of-pointers accessor
Move the resolved-resource context plumbing (resolvedKey, accessors) out of
the resource middleware and into pkg/http/handler next to ResolvedResource, so
type and accessor live in one package (matching the authtypes/ctxtypes
convention) and consumers import a single package.
- Store []*ResolvedResource instead of *[]ResolvedResource; in-place response-id
finalization still works via the element pointers.
- ResolvedResourcesFromContext returns an error (errCodeResolvedResourcesNotFound)
instead of a bool; authz surfaces it, audit treats absence as a no-op.
- Drop the now-dead authz Check/CheckAll/AuthZCheckGroup helpers superseded by
CheckResources.
* refactor(resource): unify id resolution into a single phase-driven mechanism
Replace the two-shaped id mechanism (a resolved string plus a stashed
responseID extractor, decided by resolveID's magic tuple and a zero-value
sentinel) with one retained extractor whose phase decides when it runs.
- ResolvedResource/ResolvedRelated keep idExtractor (renamed from responseID);
it is run in its declared phase, never re-run.
- ResourceIDExtractor gains isPhase + runFor; ResolvedResource gains resolve,
called once per phase (request by the resource middleware, response by audit).
- resolveID and resolveRelated(ec) are gone; FinalizeResponseIDs collapses to a
single resolve(phaseResponse) call. Request and response resolution are now
symmetric.
* refactor(resource): split resourcedef.go along its logical seams
Break the ~320-line resourcedef.go into cohesive files within the handler
package (pure relocation, no behavior or API change):
- extractor.go — extraction: ExtractorContext, phases, extractors + constructors
- resourcedef.go — declaration: ResourceDef/ResourcesDef/RelatedResource/
ResourceSpec + their functions (resolveRequest, ResolveRequest)
and the selectors
- resolved_resource.go — resolved types + their functions (resolve,
newResolvedRelated, FinalizeResponseIDs, HasResponseIDs)
- resolved_context.go — context plumbing (resolvedKey + accessors)
Each file's imports narrow to its concern; mux/gjson are now confined to
extractor.go.
* refactor(resource): extract selectors into selector.go
Move SelectorFunc + WildcardSelector/IDSelector (and the errCode they use)
out of resourcedef.go into selector.go. Pure relocation, no behavior change:
resourcedef.go now holds only the route-author declaration types and narrows
its imports to audittypes + coretypes.
* refactor(resource): extract ResourceSpec into resource_spec.go
Move the sealed ResourceSpec interface out of resourcedef.go into its own
file. Pure relocation, no behavior change.
* refactor(resource): split ResourcesDef into resourcesdef.go
Move the fan-out ResourcesDef (struct + sealResourceSpec/resolveRequest) out
of resourcedef.go into its own file. resourcedef.go keeps ResourceDef, the
shared RelatedResource, and the ResolveRequest orchestrator. Pure relocation,
no behavior change.
* refactor(resource): move RelatedResource and ResolveRequest into resource_spec.go
Cluster the spec contract together: the shared RelatedResource type and the
ResolveRequest orchestrator (over []ResourceSpec) join the ResourceSpec
interface. resourcedef.go now holds only ResourceDef. Pure relocation, no
behavior change.
* refactor(resource): seal ResourceSpec via resolveRequest alone
Drop the redundant sealResourceSpec() marker method; the unexported
resolveRequest already prevents implementations outside the package.
* feat(resource): scaffold coretypes-based resolved model
Introduce the referenceable, coretypes-resident resource model (additive;
the existing ResourceDef path is untouched and the build stays green):
- coretypes: ExtractorContext + ExtractPhase + ResourceIDExtractor/
ResourceIDsExtractor (extractor machinery moved out of handler; handler keeps
only the mux/gjson constructors).
- coretypes: SelectorFunc (now (ctx, resource, id, orgID) to stay cycle-free) +
WildcardSelector/IDSelector.
- coretypes: ResolvedResource + ResolvedResourceWithTargetResource interfaces,
their concrete types with two-phase fill (request ids at construction,
response ids via ResolveResponse), and the resolved-context accessors.
- handler: the three explicit declaration types — BasicResourceDef,
AttachDetachSiblingResourceDef, AttachDetachParentChildResourceDef.
Wiring (defs -> ResolveRequest, middleware, route migration) follows next.
* refactor(resource): wire the coretypes resolved model end-to-end
Cut the resource middleware over to the coretypes-resident resolved model and
the explicit declaration types, replacing the generic ResourceDef/ResourcesDef.
- handler: ResourceDef is now a sealed interface (unexported resolveRequest)
implemented by BasicResourceDef / AttachDetachSiblingResourceDef /
AttachDetachParentChildResourceDef, all consolidated into resourcedef.go.
Removed the old generic defs, the handler-side resolved/selector/context
(moved to coretypes), and the dead AuditDef.
- coretypes: ActionCategory moved here; Category() exposed on the resolved
interface (declared on the def, read by audit; no kind-based derivation).
- middleware: authz does M+N absolute checks (source always, sibling target
too, parent-child child never) via the resolved selectors; audit type-switches
on the resolved interface to emit per resource / per relationship.
- authz forbidden message is now AWS-style: principal is not authorized to
perform <kind>:<verb> on resource "<id>".
- routes: service account + role routes migrated to the explicit defs;
roleSelector takes orgID.
Note: resourcedef_test.go (old API) removed; new tests to follow.
* feat(resource): instrument query-range with telemetry resource authz
Authorize /api/v5/query_range at the telemetry-resource level, derived from the
request body rather than a path/body id:
- coretypes: ResourceExtractor now yields []ResourceWithID (resource + id), and
TelemetrySignalSource maps each query's spec.signal+spec.source to a telemetry
resource (via TelemetryResourceForSignalSource) and reads a per-query id — one
entry per query, no de-duplication, so repeated signals each get their own
resource + id.
- handler: TelemetryResourceDef fans out one resolved resource per query through
NewResolvedResourceWithID; resolveRequest returns a slice to allow fan-out.
- The extractor model (types + constructors + ResourceExtractor) now lives wholly
in coretypes (handler/extractor.go removed); coretypes gains mux/gjson.
- querier route: ViewAccess -> CheckResources + the telemetry def (spec.name is a
placeholder id; the owner picks the real field).
Carries the in-progress removal of Verb.IsMutation and its audit mutation-gate,
so audit currently emits per resolved resource regardless of verb (to revisit).
* feat(resource): instrument planned-maintenance routes + tidy resolved id handling
- ruler.go: downtime_schedules routes move from ViewAccess/EditAccess to
CheckResources with resource defs — Basic for list/read/create/update/delete on
PlannedMaintenance, plus a sibling Attach (schedule <-> the rules in alertIds)
on create/update so both the schedule and each rule are authz-checked.
- coretypes: SourceIDs/TargetIDs return a single empty id when there are none, so
collection-level access lives in the resolved value; authz.checkResource drops
its empty-id shim and just iterates.
- readability: expand crammed multi-arg signatures and calls (checkResource,
NewResolvedResource/WithID, forbidden errors.Newf, telemetry mapping) to one
argument per line.
* refactor(resource): drop query-range/planned-maintenance instrumentation; mirror sibling audit
- Revert /api/v5/query_range and downtime_schedules routes to ViewAccess/EditAccess
and remove the telemetry-resource scaffolding that only query-range consumed
(TelemetryResourceDef, TelemetrySignalSource, TelemetryResourceForSignalSource,
ResourceExtractor/ResourceWithID, NewResolvedResourceWithID).
- audit: a sibling attach/detach now emits the event from both ends, matching the
both-ends authz model (parent-child stays one-directional).
- Strip non-essential doc/inline comments across the resource middleware files.
* refactor(coretypes): fold extractor/selector _func files into their concept files
- Merge extractor_func.go + extractor_context.go into extractor.go, and
selector_func.go into selector.go, matching the type.go/object.go/verb.go
convention of keeping a type with its constructors and helpers.
- Order each file const/var -> type -> func (also reorders action_category.go).
* feat(resource): capture response body only when an id is resolved from it
- Restore the capture gate lost in the coretypes move: ResolvedResource gains an
unexported hasResponsePhase(), and ShouldCaptureResponseBody(ctx) drives the
audit middleware so the body is buffered only when some resolved resource reads
an id out of it (e.g. a create), not for every resource-declared route.
- Add ResourceIDsExtractor.IsPhase (mirroring ResourceIDExtractor) and reuse it.
- Fold resolved_context.go into resolved.go.
---------
Co-authored-by: grandwizard28 <vibhupandey28@gmail.com>
|
||
|
|
3d8cddf84e |
refactor: split typeable infrastructure into pkg/types/coretypes (#11105)
* refactor: move authtypes to coretypes
* refactor: migrate downstream consumers to coretypes Kind/Type/Relation
Wire all consumers of the typeable infrastructure through coretypes:
- Replace authtypes.Name/Type/Relation references with coretypes equivalents
- Switch Typeable singletons to constructor calls (authtypes.NewTypeableUser
etc.), with the embedded coretypes.Typeable populated so Kind/Type/Prefix/
Scope dispatch correctly through the embed
- Update dashboardtypes meta-resource declarations to use authtypes
constructors so they expose Tuples (authz callers need it)
- Rename Resource.Name field accesses to Resource.Kind to match the field
rename in authtypes.Resource
- Fix typeable_metaresource.go calling the plural NewTypeableMetaResources
helper — should be the singular NewTypeableMetaResource
go build ./... and go vet ./... clean (parser-generated unreachable-code
warnings are pre-existing). Authz unit tests pass.
* refactor(audittypes): unify Action with coretypes.Relation
Drop the duplicate Action enum from audittypes — the verbs (create/update/
delete) match coretypes.Relation exactly. Move PastTense onto Relation so
audit EventName derivation continues to work without a parallel hierarchy.
Also retypes AuditDef.ResourceKind from string to coretypes.Kind so audit
declarations get the same regex validation that authz already enforces.
* refactor(retentiontypes): extract TTLSetting into its own package
TTLSetting is the bun model for ClickHouse TTL settings — has nothing to do
with the Organization domain it was previously co-located with in
pkg/types/organization.go. Moved to pkg/types/retentiontypes/ alongside the
ClickHouse reader that's its sole consumer.
No schema change; the bun table tag (table:ttl_setting) is unchanged.
* chore(openapi): regenerate spec for coretypes.Relation and Resource.Kind
* chore(frontend): regenerate API client and migrate Resource.name → Resource.kind
Regenerated TypeScript API types after the AuthtypesResource field rename
and the new CoretypesRelation enum. Updated:
- frontend/scripts/generate-permissions-type.cjs to read `r.kind` from the
/api/v1/authz/resources response and emit `kind:` in the static
permissions.type.ts file.
- frontend/src/hooks/useAuthZ/{permissions.type,types,utils,useAuthZ}.tsx:
Resource.name → Resource.kind throughout.
- frontend/src/container/RolesSettings/{utils.tsx,__tests__/utils.test.ts}:
same field migration.
- frontend/src/components/createGuardedRoute/createGuardedRoute.test.tsx:
same.
- useAuthZ/utils.ts: cast string relations to CoretypesRelationDTO at the
AuthtypesTransactionDTO boundary now that relation is an enum, not a raw
string.
yarn generate:api passes (orval generation + lint + typecheck).
* refactor: migrate downstream consumers to Resource/Verb rename
* chore(openapi): regenerate spec for Resource/Verb rename
* feat(coretypes): add ListResources accessor with stable sort
* feat(cmd): add 'generate authz' subcommand for permissions type
* refactor(authz): drop runtime authz/resources endpoint
* refactor(frontend): consume static permissions.type.ts directly
* chore(frontend): regenerate Orval client without authz/resources
* ci: move authz schema check from jsci to goci
* refactor(coretypes): move Selector/Object/Transaction from authtypes
* feat(coretypes): add managed role names and permission policy
* feat(coretypes): add Registry assembling resources, types, and managed-role transactions
* refactor(authz): wire *coretypes.Registry; drop RegisterTypeable
* refactor(cmd): wire coretypes.NewRegistry into server bootstraps
* chore: regenerate openapi spec for authtypes -> coretypes type moves
* chore(frontend): regenerate API client for Authtypes -> Coretypes type moves
* refactor(coretypes): rename GettableResource to ResourceRef
* refactor(authz): collapse Registry around static data; bridge once at construction
* refactor(coretypes): tighten Registry, restore anonymous public-dashboard grant
Drops passthrough fields from coretypes.Registry; adds an O(1) lookup map
for NewResourceFromTypeAndKind; replaces stringly-typed Type compares with
Type.Equals; removes the now-redundant getUniqueTypes helper. Restores the
signoz-anonymous read grant on metaresource/public-dashboard that was
silently dropped, and removes the invalid signoz-admin/VerbCreate/TypeUser
entry that panicked at startup.
* chore: regenerate openapi spec for coretypes -> authtypes type moves
* chore(frontend): regenerate API client for Coretypes -> Authtypes type moves
* fix(authz): disambiguate kind→type by relation, preserve multi-part selectors
permissions.type.ts now lists the same kind (dashboard, role,
public-dashboard) under both metaresource and metaresources, so the prior
kind→type map silently overwrote one with the other. Resolve the type
using the requesting relation's allowed types, and slice the selector at
the first colon so multi-part selectors (e.g. id:version) round-trip
correctly. Updates useAuthZ.test.tsx to use the regenerated kind field.
* refactor(authtypes): introduce Relation wrapper over coretypes.Verb
The authz layer modeled relations as raw coretypes.Verb everywhere, which
forced authz-level concepts (action, role-binding) to share a type with
schema-level enumerations. Introduce authtypes.Relation as a thin wrapper
over coretypes.Verb so the authz APIs (CheckWithTupleCreation, ListObjects,
GetObjects, PatchObjects, NewTuples, Transaction.Relation, etc.) can grow
authz-specific affordances without leaking back into coretypes.
Also reshuffles the static coretypes data into dedicated registry_*.go files
(types, kinds, verbs, resources, managed roles) to keep the schema declarations
isolated from the value types they configure.
* refactor(authtypes): expose Relation.Enum() and regenerate openapi spec
Without an Enum() method on Relation the openapi generator emitted an
empty AuthtypesRelation schema (no allowed values). Forward the enum
from the embedded coretypes.Verb so the wire contract is faithful.
* refactor(ee/authz): drop always-nil error returns from managed-role tuple helpers
getManagedRoleGrantTuples and getManagedRoleTransactionTuples never
returned a non-nil error, which the linter (unparam) had flagged. Drop
the unused error return; callers no longer need the err check either.
* chore(frontend): regenerate API client for authtypes.Relation
* fix(authz): satisfy go-lint — keyed Relation literal, drop redundant Verb selector
* refactor(coretypes): sync Kinds slice with full registry_kind declarations
* feat(coretypes): register metaresource and metaresources for all new kinds
Adds 21 metaresource and 21 metaresources entries (covering notification-channel,
route-policy, apdex-setting, auth-domain, session, cloud-integration,
cloud-integration-service, ingestion-key, ingestion-limit, pipeline,
user-preference, org-preference, quick-filter, ttl-setting, rule,
planned-maintenance, saved-view, trace-funnel, factor-password, factor-api-key,
license) so the authz schema covers every resource Kind declared in
registry_kind. Regenerates the static frontend permissions.type.ts to match.
* feat(coretypes): populate ManagedRoleToTransactions from signozapiserver routes
Enumerates every (verb, resource) tuple each managed role holds, derived
from the AdminAccess/EditAccess/ViewAccess middleware on routes in
pkg/apiserver/signozapiserver and the legacy http_handler in
pkg/query-service/app. Admin gets 123 transactions, editor 53, viewer 25,
anonymous keeps the single public-dashboard read.
* feat(coretypes): add integration kind with full CRUD for viewer/editor/admin
Install/uninstall/list integration routes (legacy /api/v1/integrations) all
sit behind ViewAccess, so every authenticated role gets the full CRUD
surface on (metaresource, integration) and (metaresources, integration).
Regenerates the static frontend permissions.type.ts to match.
* feat(coretypes): add subscription kind alongside license, document LCRUD shape
License covers the in-product license resource (Activate/Refresh/GetActive).
Subscription is the billing lifecycle (checkout/portal/billing) served by
ee/query-service routes. Both are admin-only and modeled with a uniform
LCRUD shape; comments call out which verbs actually map to routes versus
which are placeholders for shape parity (e.g. cancellation flows through
Stripe's portal, not an in-process delete).
* feat(coretypes): model telemetryresource for logs, traces, metrics
Mirrors the telemetryresource type from ee/authz/openfgaschema/base.fga
into coretypes: a read-only Type with three Kinds (logs, traces, metrics)
matching telemetrytypes.Signal. Selector is wildcard-only for v1; future
work can narrow per-service or per-environment when the use case lands.
Every managed role (admin/editor/viewer) gets read on each signal,
matching the schema's role#assignee grant. Anonymous stays unchanged.
Regenerates the static frontend permissions.type.ts.
* feat(coretypes): add audit-logs and meter-metrics kinds under telemetryresource
Audit logs (signal=logs, source=audit) and meter metrics (signal=metrics,
source=meter) are sensitive source-qualified telemetry streams that don't
belong under the broad read-grant every role gets on regular logs/traces/
metrics. Modeled as distinct Kinds so they can be permissioned
independently. Admin-only read for now; widen on explicit ask (e.g. an
auditor flow that needs viewer access to audit-logs). Regenerates the
static frontend permissions.type.ts.
* feat(coretypes): add logs-field and traces-field kinds for stored field config
GET/POST /logs/fields and /api/v2/traces/fields manage stored, mutable
field metadata (indexed/promoted columns) over each signal. They're
configuration, not telemetry data, so they sit under metaresource rather
than telemetryresource. Viewer reads, editor/admin update; no
create/delete since POST overwrites. Plural prefix (logs-field /
traces-field) matches the signal naming.
* chore(frontend): regenerate permissions.type.ts to match generate authz output
* feat(authz): add attach permissions to fga model
* fix(tests): use role permissions instead of dashboards
* fix(authz): couple of issues with register flow
* fix(authz): public dashboard read should be anomymous
* fix(tests): integration test for public dashboard access
---------
Co-authored-by: vikrantgupta25 <vikrant@signoz.io>
|
||
|
|
726948db9e |
feat(audittypes): align types with revised schema doc (#10826)
* feat(audittypes): align types with revised schema doc Rename resource.name → resource.kind to match Typeable.Kind() rename. Move resource attributes (kind, id) from event attributes to OTel Resource, grouping events by target resource in NewPLogsFromAuditEvents. Add network.protocol.name, network.protocol.version, url.scheme to transport attributes for complete OTel semconv coverage. * refactor(audittypes): inline resourceKey struct into function scope * test(audittypes): add tests for NewPLogsFromAuditEvents Cover resource grouping: empty input, single event, same resource batched into one ResourceLogs, different resources split, same kind with different IDs split, and interleaved events grouped correctly. Verify resource attrs live on Resource (not event attributes). |
||
|
|
42415e0873 |
feat(audit): handler-level AuditDef, audit middleware, and response capture (#10791)
* feat(audit): handler-level AuditDef and response-capturing wrapper Add declarative audit instrumentation to the handler package. Routes declare an AuditDef alongside OpenAPIDef; the handler automatically captures the response status/body and emits an audit event via auditor.Audit() after every request. * refactor(audit): move audit logic to middleware, merge with logging Move audit event emission from handler to middleware layer. The handler package keeps only the AuditDef struct and AuditDefProvider interface. The logging middleware now handles both request logging and audit event emission using a single response capture, avoiding double-wrapping. Rename badResponseLoggingWriter to responseCapture with body capture on all 4xx/5xx responses (previously only 400 and 5xx). * refactor(audit): rename Logging middleware to Audit, merge into single file Delete logging.go and merge its contents into audit.go. Rename Logging/NewLogging to Audit/NewAudit. The response.go file with responseCapture is unchanged. * refactor(audit): extract NewAuditEventFromHTTPRequest factory into audittypes Move event construction to audittypes.NewAuditEventFromHTTPRequest with an AuditEventContext struct for caller-provided fields. The audittypes layer reads only transport fields from *http.Request and has no mux, authtypes, or context dependencies. The middleware pre-extracts principal, trace, error, and route fields before calling the factory. * refactor(audit): move error parsing to render.ErrorFromBody and render.ErrorTypeFromStatusCode Add render.ErrorFromBody to extract errors.JSON from a JSON-encoded ErrorResponse body, and render.ErrorTypeFromStatusCode to reverse-map HTTP status codes to error type strings. The middleware now uses these instead of local duplicates. * refactor(audit): move AuditDef onto Handler interface, consolidate files Move AuditDef() onto the Handler interface directly. All Handler implementations now carry it: handler returns the configured def, healthOpenAPIHandler returns nil. Delete the separate AuditDefProvider interface and audit.go handler file. Move excludedRoutes check before audit emission so excluded routes skip both logging and audit. * feat(audit): add option.go with AuditDef, Option, and WithAuditDef * refactor(audit): decompose AuditEvent into attribute sub-structs, add tests Decompose flat AuditEvent fields into typed sub-structs (AuditEventAuditAttributes, PrincipalAttributes, ResourceAttributes, ErrorAttributes, TransportAttributes) each with a constructor and Put(pcommon.Map) method. Simplify NewAuditEventFromHTTPRequest to accept authtypes.Claims and oteltrace IDs directly. Simplify the middleware caller accordingly. Add unit tests for the factory, outcome boundary, and principal type derivation. * refactor(audit): shorten attribute struct names, drop error message Rename AuditEventAuditAttributes to AuditAttributes, AuditEventPrincipalAttributes to PrincipalAttributes, and likewise for Resource, Error, and Transport. The package prefix already disambiguates. Remove ErrorMessage from ErrorAttributes to avoid leaking sensitive or PII data into audit logs. Error type and code are sufficient for filtering; investigators can correlate via trace ID. * fix(audit): update auditorserver test and otlphttp provider for new struct layout Update newTestEvent in server_test.go to use nested AuditAttributes and ResourceAttributes. Update otlphttpauditor provider to access PrincipalOrgID via PrincipalAttributes. Fix godot lint on attribute section comments. * fix(audit): fix gjson path in ErrorCodeFromBody, add tests Fix ErrorCodeFromBody gjson path from "errors.code" to "error.code" to match the ErrorResponse JSON structure. Add unit tests for valid error response and invalid JSON cases. * fix(audit): add CodeUnset, use ErrorCodeFromBody in middleware Add errors.CodeUnset for responses missing an error code. Update the audit middleware to use render.ErrorCodeFromBody instead of the removed render.ErrorFromBody. * test(audit): add unit tests for responseCapture Test the four meaningful behaviors: success responses don't capture body, error responses capture body, large error bodies truncate at 4096 bytes, and 204 No Content suppresses writes entirely. * fix(audit): check rw.Write return values in response_test.go * style(audit): rename want prefix to expected in test fields * refactor(audit): replace Sprintf with strings.Builder in newBody Handle edge cases where principal email, ID, or resource ID may be empty. The builder conditionally includes each segment, avoiding empty parentheses or leading spaces in the audit body. Add test cases covering all meaningful combinations: success/failure with full/partial/empty principal, resource ID, and error details. * chore: fix formatting * chore: remove json tags * fix: rebase with main |
||
|
|
2163e1ce41 |
chore(lint): enable godot and staticcheck (#10775)
* chore(lint): enable godot and staticcheck * chore(lint): merge main and fix new lint issues in main |
||
|
|
5c86b80682 |
chore: add OpenAPI spec for /v5/query_range (#10239)
Some checks failed
build-staging / staging (push) Has been cancelled
build-staging / prepare (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
|
||
|
|
de45292782 | chore: add query params to metrics explorer (#10091) | ||
|
|
8771919de6 |
feat(gen): add cobra command for generating openapi spec (#9803)
add cobra command for auto-generating openapi spec |