Compare commits

..

2 Commits

Author SHA1 Message Date
Ishan Uniyal
afc85a2d27 feat: testcase added 2026-02-23 17:59:10 +05:30
Ishan Uniyal
f1cf7a0dab feat: color fallback and red checks 2026-02-23 15:31:50 +05:30
75 changed files with 5463 additions and 6893 deletions

View File

@@ -326,9 +326,6 @@ components:
type: string
url:
type: string
required:
- code
- message
type: object
ErrorsResponseerroradditional:
properties:
@@ -1664,9 +1661,6 @@ components:
$ref: '#/components/schemas/ErrorsJSON'
status:
type: string
required:
- status
- error
type: object
RoletypesGettableResources:
properties:
@@ -2156,9 +2150,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"500":
@@ -2242,9 +2233,6 @@ paths:
$ref: '#/components/schemas/AuthtypesGettableToken'
status:
type: string
required:
- status
- data
type: object
description: See Other
"400":
@@ -2283,9 +2271,6 @@ paths:
$ref: '#/components/schemas/AuthtypesGettableToken'
status:
type: string
required:
- status
- data
type: object
description: See Other
"400":
@@ -2349,9 +2334,6 @@ paths:
$ref: '#/components/schemas/AuthtypesGettableToken'
status:
type: string
required:
- status
- data
type: object
description: See Other
"400":
@@ -2446,9 +2428,6 @@ paths:
$ref: '#/components/schemas/DashboardtypesGettablePublicDasbhboard'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -2503,9 +2482,6 @@ paths:
$ref: '#/components/schemas/TypesIdentifiable'
status:
type: string
required:
- status
- data
type: object
description: Created
"401":
@@ -2599,9 +2575,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -2649,9 +2622,6 @@ paths:
$ref: '#/components/schemas/AuthtypesGettableAuthDomain'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -2848,9 +2818,6 @@ paths:
$ref: '#/components/schemas/TelemetrytypesGettableFieldKeys'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -2941,9 +2908,6 @@ paths:
$ref: '#/components/schemas/TelemetrytypesGettableFieldValues'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -2993,9 +2957,6 @@ paths:
$ref: '#/components/schemas/TypesResetPasswordToken'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -3051,9 +3012,6 @@ paths:
$ref: '#/components/schemas/TypesGettableGlobalConfig'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -3099,9 +3057,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -3149,9 +3104,6 @@ paths:
$ref: '#/components/schemas/TypesInvite'
status:
type: string
required:
- status
- data
type: object
description: Created
"400":
@@ -3265,9 +3217,6 @@ paths:
$ref: '#/components/schemas/TypesInvite'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -3311,9 +3260,6 @@ paths:
$ref: '#/components/schemas/TypesUser'
status:
type: string
required:
- status
- data
type: object
description: Created
"400":
@@ -3408,9 +3354,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -3509,9 +3452,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -3561,9 +3501,6 @@ paths:
$ref: '#/components/schemas/PreferencetypesPreference'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -3677,9 +3614,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -3727,9 +3661,6 @@ paths:
$ref: '#/components/schemas/TypesGettableAPIKey'
status:
type: string
required:
- status
- data
type: object
description: Created
"400":
@@ -3897,9 +3828,6 @@ paths:
$ref: '#/components/schemas/DashboardtypesGettablePublicDashboardData'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -3953,9 +3881,6 @@ paths:
$ref: '#/components/schemas/Querybuildertypesv5QueryRangeResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4033,9 +3958,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4083,9 +4005,6 @@ paths:
$ref: '#/components/schemas/TypesIdentifiable'
status:
type: string
required:
- status
- data
type: object
description: Created
"400":
@@ -4220,9 +4139,6 @@ paths:
$ref: '#/components/schemas/RoletypesRole'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4346,9 +4262,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4488,9 +4401,6 @@ paths:
$ref: '#/components/schemas/RoletypesGettableResources'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4536,9 +4446,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4633,9 +4540,6 @@ paths:
$ref: '#/components/schemas/TypesUser'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4695,9 +4599,6 @@ paths:
$ref: '#/components/schemas/TypesUser'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -4753,9 +4654,6 @@ paths:
$ref: '#/components/schemas/TypesUser'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4798,9 +4696,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4850,9 +4745,6 @@ paths:
$ref: '#/components/schemas/PreferencetypesPreference'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -4995,9 +4887,6 @@ paths:
type: array
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -5050,9 +4939,6 @@ paths:
$ref: '#/components/schemas/GatewaytypesGettableIngestionKeys'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -5100,9 +4986,6 @@ paths:
$ref: '#/components/schemas/GatewaytypesGettableCreatedIngestionKey'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -5241,9 +5124,6 @@ paths:
$ref: '#/components/schemas/GatewaytypesGettableCreatedIngestionKeyLimit'
status:
type: string
required:
- status
- data
type: object
description: Created
"401":
@@ -5385,9 +5265,6 @@ paths:
$ref: '#/components/schemas/GatewaytypesGettableIngestionKeys'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -5451,9 +5328,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesListMetricsResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5509,9 +5383,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesMetricAlertsResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5578,9 +5449,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesMetricAttributesResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5636,9 +5504,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesMetricDashboardsResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5695,9 +5560,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesMetricHighlightsResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5754,9 +5616,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesMetricMetadata'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5873,9 +5732,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesStatsResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5931,9 +5787,6 @@ paths:
$ref: '#/components/schemas/MetricsexplorertypesTreemapResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -5983,9 +5836,6 @@ paths:
$ref: '#/components/schemas/TypesOrganization'
status:
type: string
required:
- status
- data
type: object
description: OK
"401":
@@ -6116,9 +5966,6 @@ paths:
$ref: '#/components/schemas/AuthtypesSessionContext'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -6156,9 +6003,6 @@ paths:
$ref: '#/components/schemas/AuthtypesGettableToken'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -6202,9 +6046,6 @@ paths:
$ref: '#/components/schemas/AuthtypesGettableToken'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -6237,9 +6078,6 @@ paths:
$ref: '#/components/schemas/ZeustypesGettableHost'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -6754,9 +6592,6 @@ paths:
$ref: '#/components/schemas/Querybuildertypesv5QueryRangeResponse'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":
@@ -6811,9 +6646,6 @@ paths:
$ref: '#/components/schemas/Querybuildertypesv5QueryRangeRequest'
status:
type: string
required:
- status
- data
type: object
description: OK
"400":

View File

@@ -1,7 +1,6 @@
package api
import (
"log/slog"
"net/http"
"time"
@@ -11,6 +10,7 @@ import (
"github.com/SigNoz/signoz/pkg/global"
"github.com/SigNoz/signoz/pkg/http/middleware"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/query-service/app/logparsingpipeline"
"github.com/SigNoz/signoz/pkg/query-service/interfaces"
@@ -27,12 +27,12 @@ type APIHandlerOptions struct {
RulesManager *rules.Manager
UsageManager *usage.Manager
IntegrationsController *integrations.Controller
CloudIntegrationsController *cloudintegrations.Controller
LogsParsingPipelineController *logparsingpipeline.LogParsingPipelineController
GatewayUrl string
// Querier Influx Interval
FluxInterval time.Duration
GlobalConfig global.Config
Logger *slog.Logger // this is present in Signoz.Instrumentation but adding for quick access
}
type APIHandler struct {
@@ -46,13 +46,13 @@ func NewAPIHandler(opts APIHandlerOptions, signoz *signoz.SigNoz, config signoz.
Reader: opts.DataConnector,
RuleManager: opts.RulesManager,
IntegrationsController: opts.IntegrationsController,
CloudIntegrationsController: opts.CloudIntegrationsController,
LogsParsingPipelineController: opts.LogsParsingPipelineController,
FluxInterval: opts.FluxInterval,
AlertmanagerAPI: alertmanager.NewAPI(signoz.Alertmanager),
LicensingAPI: httplicensing.NewLicensingAPI(signoz.Licensing),
Signoz: signoz,
QueryParserAPI: queryparser.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.QueryParser),
Logger: opts.Logger,
}, config)
if err != nil {
@@ -101,12 +101,14 @@ func (ah *APIHandler) RegisterRoutes(router *mux.Router, am *middleware.AuthZ) {
}
func (ah *APIHandler) RegisterCloudIntegrationsRoutes(router *mux.Router, am *middleware.AuthZ) {
ah.APIHandler.RegisterCloudIntegrationsRoutes(router, am)
router.HandleFunc(
"/api/v1/cloud-integrations/{cloudProvider}/accounts/generate-connection-params",
am.EditAccess(ah.CloudIntegrationsGenerateConnectionParams),
).Methods(http.MethodGet)
}
func (ah *APIHandler) getVersion(w http.ResponseWriter, r *http.Request) {

View File

@@ -6,7 +6,6 @@ import (
"encoding/json"
"fmt"
"io"
"log/slog"
"net/http"
"strings"
"time"
@@ -14,14 +13,20 @@ import (
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/modules/user"
basemodel "github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/gorilla/mux"
"go.uber.org/zap"
)
// TODO: move this file with other cloud integration related code
type CloudIntegrationConnectionParamsResponse struct {
IngestionUrl string `json:"ingestion_url,omitempty"`
IngestionKey string `json:"ingestion_key,omitempty"`
SigNozAPIUrl string `json:"signoz_api_url,omitempty"`
SigNozAPIKey string `json:"signoz_api_key,omitempty"`
}
func (ah *APIHandler) CloudIntegrationsGenerateConnectionParams(w http.ResponseWriter, r *http.Request) {
claims, err := authtypes.ClaimsFromContext(r.Context())
@@ -36,21 +41,23 @@ func (ah *APIHandler) CloudIntegrationsGenerateConnectionParams(w http.ResponseW
return
}
cloudProviderString := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
cloudProvider := mux.Vars(r)["cloudProvider"]
if cloudProvider != "aws" {
RespondError(w, basemodel.BadRequest(fmt.Errorf(
"cloud provider not supported: %s", cloudProvider,
)), nil)
return
}
apiKey, err := ah.getOrCreateCloudIntegrationPAT(r.Context(), claims.OrgID, cloudProvider)
if err != nil {
render.Error(w, err)
apiKey, apiErr := ah.getOrCreateCloudIntegrationPAT(r.Context(), claims.OrgID, cloudProvider)
if apiErr != nil {
RespondError(w, basemodel.WrapApiError(
apiErr, "couldn't provision PAT for cloud integration:",
), nil)
return
}
result := integrationtypes.GettableCloudIntegrationConnectionParams{
result := CloudIntegrationConnectionParamsResponse{
SigNozAPIKey: apiKey,
}
@@ -64,17 +71,16 @@ func (ah *APIHandler) CloudIntegrationsGenerateConnectionParams(w http.ResponseW
// Return the API Key (PAT) even if the rest of the params can not be deduced.
// Params not returned from here will be requested from the user via form inputs.
// This enables gracefully degraded but working experience even for non-cloud deployments.
ah.opts.Logger.InfoContext(
r.Context(),
"ingestion params and signoz api url can not be deduced since no license was found",
)
render.Success(w, http.StatusOK, result)
zap.L().Info("ingestion params and signoz api url can not be deduced since no license was found")
ah.Respond(w, result)
return
}
signozApiUrl, err := ah.getIngestionUrlAndSigNozAPIUrl(r.Context(), license.Key)
if err != nil {
render.Error(w, err)
signozApiUrl, apiErr := ah.getIngestionUrlAndSigNozAPIUrl(r.Context(), license.Key)
if apiErr != nil {
RespondError(w, basemodel.WrapApiError(
apiErr, "couldn't deduce ingestion url and signoz api url",
), nil)
return
}
@@ -83,41 +89,48 @@ func (ah *APIHandler) CloudIntegrationsGenerateConnectionParams(w http.ResponseW
gatewayUrl := ah.opts.GatewayUrl
if len(gatewayUrl) > 0 {
ingestionKeyString, err := ah.getOrCreateCloudProviderIngestionKey(
ingestionKey, apiErr := getOrCreateCloudProviderIngestionKey(
r.Context(), gatewayUrl, license.Key, cloudProvider,
)
if err != nil {
render.Error(w, err)
if apiErr != nil {
RespondError(w, basemodel.WrapApiError(
apiErr, "couldn't get or create ingestion key",
), nil)
return
}
result.IngestionKey = ingestionKeyString
result.IngestionKey = ingestionKey
} else {
ah.opts.Logger.InfoContext(
r.Context(),
"ingestion key can't be deduced since no gateway url has been configured",
)
zap.L().Info("ingestion key can't be deduced since no gateway url has been configured")
}
render.Success(w, http.StatusOK, result)
ah.Respond(w, result)
}
func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId string, cloudProvider valuer.String) (string, error) {
func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId string, cloudProvider string) (
string, *basemodel.ApiError,
) {
integrationPATName := fmt.Sprintf("%s integration", cloudProvider)
integrationUser, err := ah.getOrCreateCloudIntegrationUser(ctx, orgId, cloudProvider)
if err != nil {
return "", err
integrationUser, apiErr := ah.getOrCreateCloudIntegrationUser(ctx, orgId, cloudProvider)
if apiErr != nil {
return "", apiErr
}
orgIdUUID, err := valuer.NewUUID(orgId)
if err != nil {
return "", err
return "", basemodel.InternalError(fmt.Errorf(
"couldn't parse orgId: %w", err,
))
}
allPats, err := ah.Signoz.Modules.User.ListAPIKeys(ctx, orgIdUUID)
if err != nil {
return "", err
return "", basemodel.InternalError(fmt.Errorf(
"couldn't list PATs: %w", err,
))
}
for _, p := range allPats {
if p.UserID == integrationUser.ID && p.Name == integrationPATName {
@@ -125,10 +138,9 @@ func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId
}
}
ah.opts.Logger.InfoContext(
ctx,
zap.L().Info(
"no PAT found for cloud integration, creating a new one",
slog.String("cloudProvider", cloudProvider.String()),
zap.String("cloudProvider", cloudProvider),
)
newPAT, err := types.NewStorableAPIKey(
@@ -138,48 +150,68 @@ func (ah *APIHandler) getOrCreateCloudIntegrationPAT(ctx context.Context, orgId
0,
)
if err != nil {
return "", err
return "", basemodel.InternalError(fmt.Errorf(
"couldn't create cloud integration PAT: %w", err,
))
}
err = ah.Signoz.Modules.User.CreateAPIKey(ctx, newPAT)
if err != nil {
return "", err
return "", basemodel.InternalError(fmt.Errorf(
"couldn't create cloud integration PAT: %w", err,
))
}
return newPAT.Token, nil
}
// TODO: move this function out of handler and use proper module structure
func (ah *APIHandler) getOrCreateCloudIntegrationUser(ctx context.Context, orgId string, cloudProvider valuer.String) (*types.User, error) {
cloudIntegrationUserName := fmt.Sprintf("%s-integration", cloudProvider.String())
func (ah *APIHandler) getOrCreateCloudIntegrationUser(
ctx context.Context, orgId string, cloudProvider string,
) (*types.User, *basemodel.ApiError) {
cloudIntegrationUserName := fmt.Sprintf("%s-integration", cloudProvider)
email := valuer.MustNewEmail(fmt.Sprintf("%s@signoz.io", cloudIntegrationUserName))
cloudIntegrationUser, err := types.NewUser(cloudIntegrationUserName, email, types.RoleViewer, valuer.MustNewUUID(orgId))
if err != nil {
return nil, err
return nil, basemodel.InternalError(fmt.Errorf("couldn't create cloud integration user: %w", err))
}
password := types.MustGenerateFactorPassword(cloudIntegrationUser.ID.StringValue())
cloudIntegrationUser, err = ah.Signoz.Modules.User.GetOrCreateUser(ctx, cloudIntegrationUser, user.WithFactorPassword(password))
if err != nil {
return nil, err
return nil, basemodel.InternalError(fmt.Errorf("couldn't look for integration user: %w", err))
}
return cloudIntegrationUser, nil
}
// TODO: move this function out of handler and use proper module structure
func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licenseKey string) (string, error) {
respBytes, err := ah.Signoz.Zeus.GetDeployment(ctx, licenseKey)
if err != nil {
return "", errors.WrapInternalf(err, errors.CodeInternal, "couldn't query for deployment info: error")
func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licenseKey string) (
string, *basemodel.ApiError,
) {
// TODO: remove this struct from here
type deploymentResponse struct {
Name string `json:"name"`
ClusterInfo struct {
Region struct {
DNS string `json:"dns"`
} `json:"region"`
} `json:"cluster"`
}
resp := new(integrationtypes.GettableDeployment)
respBytes, err := ah.Signoz.Zeus.GetDeployment(ctx, licenseKey)
if err != nil {
return "", basemodel.InternalError(fmt.Errorf(
"couldn't query for deployment info: error: %w", err,
))
}
resp := new(deploymentResponse)
err = json.Unmarshal(respBytes, resp)
if err != nil {
return "", errors.WrapInternalf(err, errors.CodeInternal, "couldn't unmarshal deployment info response")
return "", basemodel.InternalError(fmt.Errorf(
"couldn't unmarshal deployment info response: error: %w", err,
))
}
regionDns := resp.ClusterInfo.Region.DNS
@@ -187,10 +219,9 @@ func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licens
if len(regionDns) < 1 || len(deploymentName) < 1 {
// Fail early if actual response structure and expectation here ever diverge
return "", errors.NewInternalf(
errors.CodeInternal,
return "", basemodel.InternalError(fmt.Errorf(
"deployment info response not in expected shape. couldn't determine region dns and deployment name",
)
))
}
signozApiUrl := fmt.Sprintf("https://%s.%s", deploymentName, regionDns)
@@ -198,85 +229,102 @@ func (ah *APIHandler) getIngestionUrlAndSigNozAPIUrl(ctx context.Context, licens
return signozApiUrl, nil
}
func (ah *APIHandler) getOrCreateCloudProviderIngestionKey(
ctx context.Context, gatewayUrl string, licenseKey string, cloudProvider valuer.String,
) (string, error) {
type ingestionKey struct {
Name string `json:"name"`
Value string `json:"value"`
// other attributes from gateway response not included here since they are not being used.
}
type ingestionKeysSearchResponse struct {
Status string `json:"status"`
Data []ingestionKey `json:"data"`
Error string `json:"error"`
}
type createIngestionKeyResponse struct {
Status string `json:"status"`
Data ingestionKey `json:"data"`
Error string `json:"error"`
}
func getOrCreateCloudProviderIngestionKey(
ctx context.Context, gatewayUrl string, licenseKey string, cloudProvider string,
) (string, *basemodel.ApiError) {
cloudProviderKeyName := fmt.Sprintf("%s-integration", cloudProvider)
// see if the key already exists
searchResult, err := requestGateway[integrationtypes.GettableIngestionKeysSearch](
searchResult, apiErr := requestGateway[ingestionKeysSearchResponse](
ctx,
gatewayUrl,
licenseKey,
fmt.Sprintf("/v1/workspaces/me/keys/search?name=%s", cloudProviderKeyName),
nil,
ah.opts.Logger,
)
if err != nil {
return "", err
if apiErr != nil {
return "", basemodel.WrapApiError(
apiErr, "couldn't search for cloudprovider ingestion key",
)
}
if searchResult.Status != "success" {
return "", errors.NewInternalf(
errors.CodeInternal,
"couldn't search for cloud provider ingestion key: status: %s, error: %s",
return "", basemodel.InternalError(fmt.Errorf(
"couldn't search for cloudprovider ingestion key: status: %s, error: %s",
searchResult.Status, searchResult.Error,
)
))
}
for _, k := range searchResult.Data {
if k.Name != cloudProviderKeyName {
continue
}
if k.Name == cloudProviderKeyName {
if len(k.Value) < 1 {
// Fail early if actual response structure and expectation here ever diverge
return "", basemodel.InternalError(fmt.Errorf(
"ingestion keys search response not as expected",
))
}
if len(k.Value) < 1 {
// Fail early if actual response structure and expectation here ever diverge
return "", errors.NewInternalf(errors.CodeInternal, "ingestion keys search response not as expected")
return k.Value, nil
}
return k.Value, nil
}
ah.opts.Logger.InfoContext(
ctx,
zap.L().Info(
"no existing ingestion key found for cloud integration, creating a new one",
slog.String("cloudProvider", cloudProvider.String()),
zap.String("cloudProvider", cloudProvider),
)
createKeyResult, err := requestGateway[integrationtypes.GettableCreateIngestionKey](
createKeyResult, apiErr := requestGateway[createIngestionKeyResponse](
ctx, gatewayUrl, licenseKey, "/v1/workspaces/me/keys",
map[string]any{
"name": cloudProviderKeyName,
"tags": []string{"integration", cloudProvider.String()},
"tags": []string{"integration", cloudProvider},
},
ah.opts.Logger,
)
if err != nil {
return "", err
if apiErr != nil {
return "", basemodel.WrapApiError(
apiErr, "couldn't create cloudprovider ingestion key",
)
}
if createKeyResult.Status != "success" {
return "", errors.NewInternalf(
errors.CodeInternal,
"couldn't create cloud provider ingestion key: status: %s, error: %s",
return "", basemodel.InternalError(fmt.Errorf(
"couldn't create cloudprovider ingestion key: status: %s, error: %s",
createKeyResult.Status, createKeyResult.Error,
)
))
}
ingestionKeyString := createKeyResult.Data.Value
if len(ingestionKeyString) < 1 {
ingestionKey := createKeyResult.Data.Value
if len(ingestionKey) < 1 {
// Fail early if actual response structure and expectation here ever diverge
return "", errors.NewInternalf(errors.CodeInternal,
return "", basemodel.InternalError(fmt.Errorf(
"ingestion key creation response not as expected",
)
))
}
return ingestionKeyString, nil
return ingestionKey, nil
}
func requestGateway[ResponseType any](
ctx context.Context, gatewayUrl, licenseKey, path string, payload any, logger *slog.Logger,
) (*ResponseType, error) {
ctx context.Context, gatewayUrl string, licenseKey string, path string, payload any,
) (*ResponseType, *basemodel.ApiError) {
baseUrl := strings.TrimSuffix(gatewayUrl, "/")
reqUrl := fmt.Sprintf("%s%s", baseUrl, path)
@@ -287,12 +335,13 @@ func requestGateway[ResponseType any](
"X-Consumer-Groups": "ns:default",
}
return requestAndParseResponse[ResponseType](ctx, reqUrl, headers, payload, logger)
return requestAndParseResponse[ResponseType](ctx, reqUrl, headers, payload)
}
func requestAndParseResponse[ResponseType any](
ctx context.Context, url string, headers map[string]string, payload any, logger *slog.Logger,
) (*ResponseType, error) {
ctx context.Context, url string, headers map[string]string, payload any,
) (*ResponseType, *basemodel.ApiError) {
reqMethod := http.MethodGet
var reqBody io.Reader
if payload != nil {
@@ -300,14 +349,18 @@ func requestAndParseResponse[ResponseType any](
bodyJson, err := json.Marshal(payload)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't marshal payload")
return nil, basemodel.InternalError(fmt.Errorf(
"couldn't serialize request payload to JSON: %w", err,
))
}
reqBody = bytes.NewBuffer(bodyJson)
reqBody = bytes.NewBuffer([]byte(bodyJson))
}
req, err := http.NewRequestWithContext(ctx, reqMethod, url, reqBody)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't create req")
return nil, basemodel.InternalError(fmt.Errorf(
"couldn't prepare request: %w", err,
))
}
for k, v := range headers {
@@ -320,26 +373,23 @@ func requestAndParseResponse[ResponseType any](
response, err := client.Do(req)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't make req")
return nil, basemodel.InternalError(fmt.Errorf("couldn't make request: %w", err))
}
defer func() {
err = response.Body.Close()
if err != nil {
logger.ErrorContext(ctx, "couldn't close response body", "error", err)
}
}()
defer response.Body.Close()
respBody, err := io.ReadAll(response.Body)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't read response body")
return nil, basemodel.InternalError(fmt.Errorf("couldn't read response: %w", err))
}
var resp ResponseType
err = json.Unmarshal(respBody, &resp)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't unmarshal response body")
return nil, basemodel.InternalError(fmt.Errorf(
"couldn't unmarshal gateway response into %T", resp,
))
}
return &resp, nil

View File

@@ -37,6 +37,7 @@ import (
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
baseapp "github.com/SigNoz/signoz/pkg/query-service/app"
"github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/query-service/app/logparsingpipeline"
"github.com/SigNoz/signoz/pkg/query-service/app/opamp"
@@ -120,6 +121,13 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
)
}
cloudIntegrationsController, err := cloudintegrations.NewController(signoz.SQLStore)
if err != nil {
return nil, fmt.Errorf(
"couldn't create cloud provider integrations controller: %w", err,
)
}
// ingestion pipelines manager
logParsingPipelineController, err := logparsingpipeline.NewLogParsingPipelinesController(
signoz.SQLStore,
@@ -153,11 +161,11 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
RulesManager: rm,
UsageManager: usageManager,
IntegrationsController: integrationsController,
CloudIntegrationsController: cloudIntegrationsController,
LogsParsingPipelineController: logParsingPipelineController,
FluxInterval: config.Querier.FluxInterval,
GatewayUrl: config.Gateway.URL.String(),
GlobalConfig: config.Global,
Logger: signoz.Instrumentation.Logger(),
}
apiHandler, err := api.NewAPIHandler(apiOpts, signoz, config)

View File

@@ -25,13 +25,13 @@ export default defineConfig({
useMutation: true,
useInvalidate: true,
signal: true,
useOperationIdAsQueryKey: false,
useOperationIdAsQueryKey: true,
},
useDates: true,
useNamedParameters: true,
enumGenerationType: 'enum',
mutator: {
path: './src/api/generatedAPIInstance.ts',
path: './src/api/index.ts',
name: 'GeneratedAPIInstance',
},

View File

@@ -1,48 +0,0 @@
import { RenderErrorResponseDTO } from 'api/generated/services/sigNoz.schemas';
import { AxiosError } from 'axios';
import APIError from 'types/api/error';
// Handles errors from generated API hooks (which use RenderErrorResponseDTO)
export function ErrorResponseHandlerForGeneratedAPIs(
error: AxiosError<RenderErrorResponseDTO>,
): never {
const { response, request } = error;
// The request was made and the server responded with a status code
// that falls out of the range of 2xx
if (response) {
throw new APIError({
httpStatusCode: response.status || 500,
error: {
code: response.data.error.code,
message: response.data.error.message,
url: response.data.error.url ?? '',
errors: (response.data.error.errors ?? []).map((e) => ({
message: e.message ?? '',
})),
},
});
}
// The request was made but no response was received
if (request) {
throw new APIError({
httpStatusCode: error.status || 500,
error: {
code: error.code || error.name,
message: error.message,
url: '',
errors: [],
},
});
}
// Something happened in setting up the request that triggered an Error
throw new APIError({
httpStatusCode: error.status || 500,
error: {
code: error.name,
message: error.message,
url: '',
errors: [],
},
});
}

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
AuthtypesPostableAuthDomainDTO,
AuthtypesUpdateableAuthDomainDTO,
@@ -46,12 +45,12 @@ export const listAuthDomains = (signal?: AbortSignal) => {
};
export const getListAuthDomainsQueryKey = () => {
return [`/api/v1/domains`] as const;
return ['listAuthDomains'] as const;
};
export const getListAuthDomainsQueryOptions = <
TData = Awaited<ReturnType<typeof listAuthDomains>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listAuthDomains>>,
@@ -77,7 +76,7 @@ export const getListAuthDomainsQueryOptions = <
export type ListAuthDomainsQueryResult = NonNullable<
Awaited<ReturnType<typeof listAuthDomains>>
>;
export type ListAuthDomainsQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListAuthDomainsQueryError = RenderErrorResponseDTO;
/**
* @summary List all auth domains
@@ -85,7 +84,7 @@ export type ListAuthDomainsQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListAuthDomains<
TData = Awaited<ReturnType<typeof listAuthDomains>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listAuthDomains>>,
@@ -124,7 +123,7 @@ export const invalidateListAuthDomains = async (
* @summary Create auth domain
*/
export const createAuthDomain = (
authtypesPostableAuthDomainDTO: BodyType<AuthtypesPostableAuthDomainDTO>,
authtypesPostableAuthDomainDTO: AuthtypesPostableAuthDomainDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateAuthDomain200>({
@@ -137,19 +136,19 @@ export const createAuthDomain = (
};
export const getCreateAuthDomainMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: BodyType<AuthtypesPostableAuthDomainDTO> },
{ data: AuthtypesPostableAuthDomainDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: BodyType<AuthtypesPostableAuthDomainDTO> },
{ data: AuthtypesPostableAuthDomainDTO },
TContext
> => {
const mutationKey = ['createAuthDomain'];
@@ -163,7 +162,7 @@ export const getCreateAuthDomainMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createAuthDomain>>,
{ data: BodyType<AuthtypesPostableAuthDomainDTO> }
{ data: AuthtypesPostableAuthDomainDTO }
> = (props) => {
const { data } = props ?? {};
@@ -176,26 +175,26 @@ export const getCreateAuthDomainMutationOptions = <
export type CreateAuthDomainMutationResult = NonNullable<
Awaited<ReturnType<typeof createAuthDomain>>
>;
export type CreateAuthDomainMutationBody = BodyType<AuthtypesPostableAuthDomainDTO>;
export type CreateAuthDomainMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateAuthDomainMutationBody = AuthtypesPostableAuthDomainDTO;
export type CreateAuthDomainMutationError = RenderErrorResponseDTO;
/**
* @summary Create auth domain
*/
export const useCreateAuthDomain = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: BodyType<AuthtypesPostableAuthDomainDTO> },
{ data: AuthtypesPostableAuthDomainDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createAuthDomain>>,
TError,
{ data: BodyType<AuthtypesPostableAuthDomainDTO> },
{ data: AuthtypesPostableAuthDomainDTO },
TContext
> => {
const mutationOptions = getCreateAuthDomainMutationOptions(options);
@@ -214,7 +213,7 @@ export const deleteAuthDomain = ({ id }: DeleteAuthDomainPathParameters) => {
};
export const getDeleteAuthDomainMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -254,13 +253,13 @@ export type DeleteAuthDomainMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteAuthDomain>>
>;
export type DeleteAuthDomainMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeleteAuthDomainMutationError = RenderErrorResponseDTO;
/**
* @summary Delete auth domain
*/
export const useDeleteAuthDomain = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -285,7 +284,7 @@ export const useDeleteAuthDomain = <
*/
export const updateAuthDomain = (
{ id }: UpdateAuthDomainPathParameters,
authtypesUpdateableAuthDomainDTO: BodyType<AuthtypesUpdateableAuthDomainDTO>,
authtypesUpdateableAuthDomainDTO: AuthtypesUpdateableAuthDomainDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/domains/${id}`,
@@ -296,7 +295,7 @@ export const updateAuthDomain = (
};
export const getUpdateAuthDomainMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -304,7 +303,7 @@ export const getUpdateAuthDomainMutationOptions = <
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: BodyType<AuthtypesUpdateableAuthDomainDTO>;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
>;
@@ -313,7 +312,7 @@ export const getUpdateAuthDomainMutationOptions = <
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: BodyType<AuthtypesUpdateableAuthDomainDTO>;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
> => {
@@ -330,7 +329,7 @@ export const getUpdateAuthDomainMutationOptions = <
Awaited<ReturnType<typeof updateAuthDomain>>,
{
pathParams: UpdateAuthDomainPathParameters;
data: BodyType<AuthtypesUpdateableAuthDomainDTO>;
data: AuthtypesUpdateableAuthDomainDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -344,14 +343,14 @@ export const getUpdateAuthDomainMutationOptions = <
export type UpdateAuthDomainMutationResult = NonNullable<
Awaited<ReturnType<typeof updateAuthDomain>>
>;
export type UpdateAuthDomainMutationBody = BodyType<AuthtypesUpdateableAuthDomainDTO>;
export type UpdateAuthDomainMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateAuthDomainMutationBody = AuthtypesUpdateableAuthDomainDTO;
export type UpdateAuthDomainMutationError = RenderErrorResponseDTO;
/**
* @summary Update auth domain
*/
export const useUpdateAuthDomain = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -359,7 +358,7 @@ export const useUpdateAuthDomain = <
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: BodyType<AuthtypesUpdateableAuthDomainDTO>;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
>;
@@ -368,7 +367,7 @@ export const useUpdateAuthDomain = <
TError,
{
pathParams: UpdateAuthDomainPathParameters;
data: BodyType<AuthtypesUpdateableAuthDomainDTO>;
data: AuthtypesUpdateableAuthDomainDTO;
},
TContext
> => {

View File

@@ -11,8 +11,7 @@ import type {
} from 'react-query';
import { useMutation } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
AuthtypesTransactionDTO,
AuthzCheck200,
@@ -28,7 +27,7 @@ type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
* @summary Check permissions
*/
export const authzCheck = (
authtypesTransactionDTO: BodyType<AuthtypesTransactionDTO[]>,
authtypesTransactionDTO: AuthtypesTransactionDTO[],
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<AuthzCheck200>({
@@ -41,19 +40,19 @@ export const authzCheck = (
};
export const getAuthzCheckMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof authzCheck>>,
TError,
{ data: BodyType<AuthtypesTransactionDTO[]> },
{ data: AuthtypesTransactionDTO[] },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof authzCheck>>,
TError,
{ data: BodyType<AuthtypesTransactionDTO[]> },
{ data: AuthtypesTransactionDTO[] },
TContext
> => {
const mutationKey = ['authzCheck'];
@@ -67,7 +66,7 @@ export const getAuthzCheckMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof authzCheck>>,
{ data: BodyType<AuthtypesTransactionDTO[]> }
{ data: AuthtypesTransactionDTO[] }
> = (props) => {
const { data } = props ?? {};
@@ -80,26 +79,26 @@ export const getAuthzCheckMutationOptions = <
export type AuthzCheckMutationResult = NonNullable<
Awaited<ReturnType<typeof authzCheck>>
>;
export type AuthzCheckMutationBody = BodyType<AuthtypesTransactionDTO[]>;
export type AuthzCheckMutationError = ErrorType<RenderErrorResponseDTO>;
export type AuthzCheckMutationBody = AuthtypesTransactionDTO[];
export type AuthzCheckMutationError = RenderErrorResponseDTO;
/**
* @summary Check permissions
*/
export const useAuthzCheck = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof authzCheck>>,
TError,
{ data: BodyType<AuthtypesTransactionDTO[]> },
{ data: AuthtypesTransactionDTO[] },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof authzCheck>>,
TError,
{ data: BodyType<AuthtypesTransactionDTO[]> },
{ data: AuthtypesTransactionDTO[] },
TContext
> => {
const mutationOptions = getAuthzCheckMutationOptions(options);

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
CreatePublicDashboard201,
CreatePublicDashboardPathParameters,
@@ -53,7 +52,7 @@ export const deletePublicDashboard = ({
};
export const getDeletePublicDashboardMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -93,13 +92,13 @@ export type DeletePublicDashboardMutationResult = NonNullable<
Awaited<ReturnType<typeof deletePublicDashboard>>
>;
export type DeletePublicDashboardMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeletePublicDashboardMutationError = RenderErrorResponseDTO;
/**
* @summary Delete public dashboard
*/
export const useDeletePublicDashboard = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -136,12 +135,12 @@ export const getPublicDashboard = (
export const getGetPublicDashboardQueryKey = ({
id,
}: GetPublicDashboardPathParameters) => {
return [`/api/v1/dashboards/${id}/public`] as const;
return ['getPublicDashboard'] as const;
};
export const getGetPublicDashboardQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboard>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardPathParameters,
options?: {
@@ -176,7 +175,7 @@ export const getGetPublicDashboardQueryOptions = <
export type GetPublicDashboardQueryResult = NonNullable<
Awaited<ReturnType<typeof getPublicDashboard>>
>;
export type GetPublicDashboardQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetPublicDashboardQueryError = RenderErrorResponseDTO;
/**
* @summary Get public dashboard
@@ -184,7 +183,7 @@ export type GetPublicDashboardQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetPublicDashboard<
TData = Awaited<ReturnType<typeof getPublicDashboard>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardPathParameters,
options?: {
@@ -228,7 +227,7 @@ export const invalidateGetPublicDashboard = async (
*/
export const createPublicDashboard = (
{ id }: CreatePublicDashboardPathParameters,
dashboardtypesPostablePublicDashboardDTO: BodyType<DashboardtypesPostablePublicDashboardDTO>,
dashboardtypesPostablePublicDashboardDTO: DashboardtypesPostablePublicDashboardDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreatePublicDashboard201>({
@@ -241,7 +240,7 @@ export const createPublicDashboard = (
};
export const getCreatePublicDashboardMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -249,7 +248,7 @@ export const getCreatePublicDashboardMutationOptions = <
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: BodyType<DashboardtypesPostablePublicDashboardDTO>;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
>;
@@ -258,7 +257,7 @@ export const getCreatePublicDashboardMutationOptions = <
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: BodyType<DashboardtypesPostablePublicDashboardDTO>;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
> => {
@@ -275,7 +274,7 @@ export const getCreatePublicDashboardMutationOptions = <
Awaited<ReturnType<typeof createPublicDashboard>>,
{
pathParams: CreatePublicDashboardPathParameters;
data: BodyType<DashboardtypesPostablePublicDashboardDTO>;
data: DashboardtypesPostablePublicDashboardDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -289,14 +288,14 @@ export const getCreatePublicDashboardMutationOptions = <
export type CreatePublicDashboardMutationResult = NonNullable<
Awaited<ReturnType<typeof createPublicDashboard>>
>;
export type CreatePublicDashboardMutationBody = BodyType<DashboardtypesPostablePublicDashboardDTO>;
export type CreatePublicDashboardMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreatePublicDashboardMutationBody = DashboardtypesPostablePublicDashboardDTO;
export type CreatePublicDashboardMutationError = RenderErrorResponseDTO;
/**
* @summary Create public dashboard
*/
export const useCreatePublicDashboard = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -304,7 +303,7 @@ export const useCreatePublicDashboard = <
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: BodyType<DashboardtypesPostablePublicDashboardDTO>;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
>;
@@ -313,7 +312,7 @@ export const useCreatePublicDashboard = <
TError,
{
pathParams: CreatePublicDashboardPathParameters;
data: BodyType<DashboardtypesPostablePublicDashboardDTO>;
data: DashboardtypesPostablePublicDashboardDTO;
},
TContext
> => {
@@ -327,7 +326,7 @@ export const useCreatePublicDashboard = <
*/
export const updatePublicDashboard = (
{ id }: UpdatePublicDashboardPathParameters,
dashboardtypesUpdatablePublicDashboardDTO: BodyType<DashboardtypesUpdatablePublicDashboardDTO>,
dashboardtypesUpdatablePublicDashboardDTO: DashboardtypesUpdatablePublicDashboardDTO,
) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/dashboards/${id}/public`,
@@ -338,7 +337,7 @@ export const updatePublicDashboard = (
};
export const getUpdatePublicDashboardMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -346,7 +345,7 @@ export const getUpdatePublicDashboardMutationOptions = <
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: BodyType<DashboardtypesUpdatablePublicDashboardDTO>;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
>;
@@ -355,7 +354,7 @@ export const getUpdatePublicDashboardMutationOptions = <
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: BodyType<DashboardtypesUpdatablePublicDashboardDTO>;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
> => {
@@ -372,7 +371,7 @@ export const getUpdatePublicDashboardMutationOptions = <
Awaited<ReturnType<typeof updatePublicDashboard>>,
{
pathParams: UpdatePublicDashboardPathParameters;
data: BodyType<DashboardtypesUpdatablePublicDashboardDTO>;
data: DashboardtypesUpdatablePublicDashboardDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -386,14 +385,14 @@ export const getUpdatePublicDashboardMutationOptions = <
export type UpdatePublicDashboardMutationResult = NonNullable<
Awaited<ReturnType<typeof updatePublicDashboard>>
>;
export type UpdatePublicDashboardMutationBody = BodyType<DashboardtypesUpdatablePublicDashboardDTO>;
export type UpdatePublicDashboardMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdatePublicDashboardMutationBody = DashboardtypesUpdatablePublicDashboardDTO;
export type UpdatePublicDashboardMutationError = RenderErrorResponseDTO;
/**
* @summary Update public dashboard
*/
export const useUpdatePublicDashboard = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -401,7 +400,7 @@ export const useUpdatePublicDashboard = <
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: BodyType<DashboardtypesUpdatablePublicDashboardDTO>;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
>;
@@ -410,7 +409,7 @@ export const useUpdatePublicDashboard = <
TError,
{
pathParams: UpdatePublicDashboardPathParameters;
data: BodyType<DashboardtypesUpdatablePublicDashboardDTO>;
data: DashboardtypesUpdatablePublicDashboardDTO;
},
TContext
> => {
@@ -436,12 +435,12 @@ export const getPublicDashboardData = (
export const getGetPublicDashboardDataQueryKey = ({
id,
}: GetPublicDashboardDataPathParameters) => {
return [`/api/v1/public/dashboards/${id}`] as const;
return ['getPublicDashboardData'] as const;
};
export const getGetPublicDashboardDataQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboardData>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardDataPathParameters,
options?: {
@@ -476,7 +475,7 @@ export const getGetPublicDashboardDataQueryOptions = <
export type GetPublicDashboardDataQueryResult = NonNullable<
Awaited<ReturnType<typeof getPublicDashboardData>>
>;
export type GetPublicDashboardDataQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetPublicDashboardDataQueryError = RenderErrorResponseDTO;
/**
* @summary Get public dashboard data
@@ -484,7 +483,7 @@ export type GetPublicDashboardDataQueryError = ErrorType<RenderErrorResponseDTO>
export function useGetPublicDashboardData<
TData = Awaited<ReturnType<typeof getPublicDashboardData>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetPublicDashboardDataPathParameters,
options?: {
@@ -541,12 +540,12 @@ export const getGetPublicDashboardWidgetQueryRangeQueryKey = ({
id,
idx,
}: GetPublicDashboardWidgetQueryRangePathParameters) => {
return [`/api/v1/public/dashboards/${id}/widgets/${idx}/query_range`] as const;
return ['getPublicDashboardWidgetQueryRange'] as const;
};
export const getGetPublicDashboardWidgetQueryRangeQueryOptions = <
TData = Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id, idx }: GetPublicDashboardWidgetQueryRangePathParameters,
options?: {
@@ -582,7 +581,7 @@ export const getGetPublicDashboardWidgetQueryRangeQueryOptions = <
export type GetPublicDashboardWidgetQueryRangeQueryResult = NonNullable<
Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>
>;
export type GetPublicDashboardWidgetQueryRangeQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetPublicDashboardWidgetQueryRangeQueryError = RenderErrorResponseDTO;
/**
* @summary Get query range result
@@ -590,7 +589,7 @@ export type GetPublicDashboardWidgetQueryRangeQueryError = ErrorType<RenderError
export function useGetPublicDashboardWidgetQueryRange<
TData = Awaited<ReturnType<typeof getPublicDashboardWidgetQueryRange>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id, idx }: GetPublicDashboardWidgetQueryRangePathParameters,
options?: {

View File

@@ -14,8 +14,7 @@ import type {
} from 'react-query';
import { useQuery } from 'react-query';
import type { ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type { GetFeatures200, RenderErrorResponseDTO } from '../sigNoz.schemas';
type AwaitedInput<T> = PromiseLike<T> | T;
@@ -35,12 +34,12 @@ export const getFeatures = (signal?: AbortSignal) => {
};
export const getGetFeaturesQueryKey = () => {
return [`/api/v2/features`] as const;
return ['getFeatures'] as const;
};
export const getGetFeaturesQueryOptions = <
TData = Awaited<ReturnType<typeof getFeatures>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getFeatures>>,
@@ -66,7 +65,7 @@ export const getGetFeaturesQueryOptions = <
export type GetFeaturesQueryResult = NonNullable<
Awaited<ReturnType<typeof getFeatures>>
>;
export type GetFeaturesQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetFeaturesQueryError = RenderErrorResponseDTO;
/**
* @summary Get features
@@ -74,7 +73,7 @@ export type GetFeaturesQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetFeatures<
TData = Awaited<ReturnType<typeof getFeatures>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getFeatures>>,

View File

@@ -14,8 +14,7 @@ import type {
} from 'react-query';
import { useQuery } from 'react-query';
import type { ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
GetFieldsKeys200,
GetFieldsKeysParams,
@@ -45,12 +44,12 @@ export const getFieldsKeys = (
};
export const getGetFieldsKeysQueryKey = (params?: GetFieldsKeysParams) => {
return [`/api/v1/fields/keys`, ...(params ? [params] : [])] as const;
return ['getFieldsKeys', ...(params ? [params] : [])] as const;
};
export const getGetFieldsKeysQueryOptions = <
TData = Awaited<ReturnType<typeof getFieldsKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: GetFieldsKeysParams,
options?: {
@@ -79,7 +78,7 @@ export const getGetFieldsKeysQueryOptions = <
export type GetFieldsKeysQueryResult = NonNullable<
Awaited<ReturnType<typeof getFieldsKeys>>
>;
export type GetFieldsKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetFieldsKeysQueryError = RenderErrorResponseDTO;
/**
* @summary Get field keys
@@ -87,7 +86,7 @@ export type GetFieldsKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetFieldsKeys<
TData = Awaited<ReturnType<typeof getFieldsKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: GetFieldsKeysParams,
options?: {
@@ -142,12 +141,12 @@ export const getFieldsValues = (
};
export const getGetFieldsValuesQueryKey = (params?: GetFieldsValuesParams) => {
return [`/api/v1/fields/values`, ...(params ? [params] : [])] as const;
return ['getFieldsValues', ...(params ? [params] : [])] as const;
};
export const getGetFieldsValuesQueryOptions = <
TData = Awaited<ReturnType<typeof getFieldsValues>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: GetFieldsValuesParams,
options?: {
@@ -176,7 +175,7 @@ export const getGetFieldsValuesQueryOptions = <
export type GetFieldsValuesQueryResult = NonNullable<
Awaited<ReturnType<typeof getFieldsValues>>
>;
export type GetFieldsValuesQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetFieldsValuesQueryError = RenderErrorResponseDTO;
/**
* @summary Get field values
@@ -184,7 +183,7 @@ export type GetFieldsValuesQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetFieldsValues<
TData = Awaited<ReturnType<typeof getFieldsValues>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: GetFieldsValuesParams,
options?: {

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
CreateIngestionKey200,
CreateIngestionKeyLimit201,
@@ -60,15 +59,12 @@ export const getIngestionKeys = (
export const getGetIngestionKeysQueryKey = (
params?: GetIngestionKeysParams,
) => {
return [
`/api/v2/gateway/ingestion_keys`,
...(params ? [params] : []),
] as const;
return ['getIngestionKeys', ...(params ? [params] : [])] as const;
};
export const getGetIngestionKeysQueryOptions = <
TData = Awaited<ReturnType<typeof getIngestionKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: GetIngestionKeysParams,
options?: {
@@ -97,7 +93,7 @@ export const getGetIngestionKeysQueryOptions = <
export type GetIngestionKeysQueryResult = NonNullable<
Awaited<ReturnType<typeof getIngestionKeys>>
>;
export type GetIngestionKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetIngestionKeysQueryError = RenderErrorResponseDTO;
/**
* @summary Get ingestion keys for workspace
@@ -105,7 +101,7 @@ export type GetIngestionKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetIngestionKeys<
TData = Awaited<ReturnType<typeof getIngestionKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: GetIngestionKeysParams,
options?: {
@@ -148,7 +144,7 @@ export const invalidateGetIngestionKeys = async (
* @summary Create ingestion key for workspace
*/
export const createIngestionKey = (
gatewaytypesPostableIngestionKeyDTO: BodyType<GatewaytypesPostableIngestionKeyDTO>,
gatewaytypesPostableIngestionKeyDTO: GatewaytypesPostableIngestionKeyDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateIngestionKey200>({
@@ -161,19 +157,19 @@ export const createIngestionKey = (
};
export const getCreateIngestionKeyMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: BodyType<GatewaytypesPostableIngestionKeyDTO> },
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: BodyType<GatewaytypesPostableIngestionKeyDTO> },
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
> => {
const mutationKey = ['createIngestionKey'];
@@ -187,7 +183,7 @@ export const getCreateIngestionKeyMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createIngestionKey>>,
{ data: BodyType<GatewaytypesPostableIngestionKeyDTO> }
{ data: GatewaytypesPostableIngestionKeyDTO }
> = (props) => {
const { data } = props ?? {};
@@ -200,26 +196,26 @@ export const getCreateIngestionKeyMutationOptions = <
export type CreateIngestionKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof createIngestionKey>>
>;
export type CreateIngestionKeyMutationBody = BodyType<GatewaytypesPostableIngestionKeyDTO>;
export type CreateIngestionKeyMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateIngestionKeyMutationBody = GatewaytypesPostableIngestionKeyDTO;
export type CreateIngestionKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Create ingestion key for workspace
*/
export const useCreateIngestionKey = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: BodyType<GatewaytypesPostableIngestionKeyDTO> },
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createIngestionKey>>,
TError,
{ data: BodyType<GatewaytypesPostableIngestionKeyDTO> },
{ data: GatewaytypesPostableIngestionKeyDTO },
TContext
> => {
const mutationOptions = getCreateIngestionKeyMutationOptions(options);
@@ -240,7 +236,7 @@ export const deleteIngestionKey = ({
};
export const getDeleteIngestionKeyMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -280,13 +276,13 @@ export type DeleteIngestionKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteIngestionKey>>
>;
export type DeleteIngestionKeyMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeleteIngestionKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Delete ingestion key for workspace
*/
export const useDeleteIngestionKey = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -311,7 +307,7 @@ export const useDeleteIngestionKey = <
*/
export const updateIngestionKey = (
{ keyId }: UpdateIngestionKeyPathParameters,
gatewaytypesPostableIngestionKeyDTO: BodyType<GatewaytypesPostableIngestionKeyDTO>,
gatewaytypesPostableIngestionKeyDTO: GatewaytypesPostableIngestionKeyDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/${keyId}`,
@@ -322,7 +318,7 @@ export const updateIngestionKey = (
};
export const getUpdateIngestionKeyMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -330,7 +326,7 @@ export const getUpdateIngestionKeyMutationOptions = <
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyDTO>;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
>;
@@ -339,7 +335,7 @@ export const getUpdateIngestionKeyMutationOptions = <
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyDTO>;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
> => {
@@ -356,7 +352,7 @@ export const getUpdateIngestionKeyMutationOptions = <
Awaited<ReturnType<typeof updateIngestionKey>>,
{
pathParams: UpdateIngestionKeyPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyDTO>;
data: GatewaytypesPostableIngestionKeyDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -370,14 +366,14 @@ export const getUpdateIngestionKeyMutationOptions = <
export type UpdateIngestionKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof updateIngestionKey>>
>;
export type UpdateIngestionKeyMutationBody = BodyType<GatewaytypesPostableIngestionKeyDTO>;
export type UpdateIngestionKeyMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateIngestionKeyMutationBody = GatewaytypesPostableIngestionKeyDTO;
export type UpdateIngestionKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Update ingestion key for workspace
*/
export const useUpdateIngestionKey = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -385,7 +381,7 @@ export const useUpdateIngestionKey = <
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyDTO>;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
>;
@@ -394,7 +390,7 @@ export const useUpdateIngestionKey = <
TError,
{
pathParams: UpdateIngestionKeyPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyDTO>;
data: GatewaytypesPostableIngestionKeyDTO;
},
TContext
> => {
@@ -408,7 +404,7 @@ export const useUpdateIngestionKey = <
*/
export const createIngestionKeyLimit = (
{ keyId }: CreateIngestionKeyLimitPathParameters,
gatewaytypesPostableIngestionKeyLimitDTO: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>,
gatewaytypesPostableIngestionKeyLimitDTO: GatewaytypesPostableIngestionKeyLimitDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateIngestionKeyLimit201>({
@@ -421,7 +417,7 @@ export const createIngestionKeyLimit = (
};
export const getCreateIngestionKeyLimitMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -429,7 +425,7 @@ export const getCreateIngestionKeyLimitMutationOptions = <
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
>;
@@ -438,7 +434,7 @@ export const getCreateIngestionKeyLimitMutationOptions = <
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
> => {
@@ -455,7 +451,7 @@ export const getCreateIngestionKeyLimitMutationOptions = <
Awaited<ReturnType<typeof createIngestionKeyLimit>>,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
data: GatewaytypesPostableIngestionKeyLimitDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -469,14 +465,14 @@ export const getCreateIngestionKeyLimitMutationOptions = <
export type CreateIngestionKeyLimitMutationResult = NonNullable<
Awaited<ReturnType<typeof createIngestionKeyLimit>>
>;
export type CreateIngestionKeyLimitMutationBody = BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
export type CreateIngestionKeyLimitMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateIngestionKeyLimitMutationBody = GatewaytypesPostableIngestionKeyLimitDTO;
export type CreateIngestionKeyLimitMutationError = RenderErrorResponseDTO;
/**
* @summary Create limit for the ingestion key
*/
export const useCreateIngestionKeyLimit = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -484,7 +480,7 @@ export const useCreateIngestionKeyLimit = <
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
>;
@@ -493,7 +489,7 @@ export const useCreateIngestionKeyLimit = <
TError,
{
pathParams: CreateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesPostableIngestionKeyLimitDTO>;
data: GatewaytypesPostableIngestionKeyLimitDTO;
},
TContext
> => {
@@ -515,7 +511,7 @@ export const deleteIngestionKeyLimit = ({
};
export const getDeleteIngestionKeyLimitMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -555,13 +551,13 @@ export type DeleteIngestionKeyLimitMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteIngestionKeyLimit>>
>;
export type DeleteIngestionKeyLimitMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeleteIngestionKeyLimitMutationError = RenderErrorResponseDTO;
/**
* @summary Delete limit for the ingestion key
*/
export const useDeleteIngestionKeyLimit = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -586,7 +582,7 @@ export const useDeleteIngestionKeyLimit = <
*/
export const updateIngestionKeyLimit = (
{ limitId }: UpdateIngestionKeyLimitPathParameters,
gatewaytypesUpdatableIngestionKeyLimitDTO: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>,
gatewaytypesUpdatableIngestionKeyLimitDTO: GatewaytypesUpdatableIngestionKeyLimitDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/gateway/ingestion_keys/limits/${limitId}`,
@@ -597,7 +593,7 @@ export const updateIngestionKeyLimit = (
};
export const getUpdateIngestionKeyLimitMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -605,7 +601,7 @@ export const getUpdateIngestionKeyLimitMutationOptions = <
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
>;
@@ -614,7 +610,7 @@ export const getUpdateIngestionKeyLimitMutationOptions = <
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
> => {
@@ -631,7 +627,7 @@ export const getUpdateIngestionKeyLimitMutationOptions = <
Awaited<ReturnType<typeof updateIngestionKeyLimit>>,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -645,14 +641,14 @@ export const getUpdateIngestionKeyLimitMutationOptions = <
export type UpdateIngestionKeyLimitMutationResult = NonNullable<
Awaited<ReturnType<typeof updateIngestionKeyLimit>>
>;
export type UpdateIngestionKeyLimitMutationBody = BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
export type UpdateIngestionKeyLimitMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateIngestionKeyLimitMutationBody = GatewaytypesUpdatableIngestionKeyLimitDTO;
export type UpdateIngestionKeyLimitMutationError = RenderErrorResponseDTO;
/**
* @summary Update limit for the ingestion key
*/
export const useUpdateIngestionKeyLimit = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -660,7 +656,7 @@ export const useUpdateIngestionKeyLimit = <
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
>;
@@ -669,7 +665,7 @@ export const useUpdateIngestionKeyLimit = <
TError,
{
pathParams: UpdateIngestionKeyLimitPathParameters;
data: BodyType<GatewaytypesUpdatableIngestionKeyLimitDTO>;
data: GatewaytypesUpdatableIngestionKeyLimitDTO;
},
TContext
> => {
@@ -696,15 +692,12 @@ export const searchIngestionKeys = (
export const getSearchIngestionKeysQueryKey = (
params?: SearchIngestionKeysParams,
) => {
return [
`/api/v2/gateway/ingestion_keys/search`,
...(params ? [params] : []),
] as const;
return ['searchIngestionKeys', ...(params ? [params] : [])] as const;
};
export const getSearchIngestionKeysQueryOptions = <
TData = Awaited<ReturnType<typeof searchIngestionKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params: SearchIngestionKeysParams,
options?: {
@@ -734,7 +727,7 @@ export const getSearchIngestionKeysQueryOptions = <
export type SearchIngestionKeysQueryResult = NonNullable<
Awaited<ReturnType<typeof searchIngestionKeys>>
>;
export type SearchIngestionKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export type SearchIngestionKeysQueryError = RenderErrorResponseDTO;
/**
* @summary Search ingestion keys for workspace
@@ -742,7 +735,7 @@ export type SearchIngestionKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export function useSearchIngestionKeys<
TData = Awaited<ReturnType<typeof searchIngestionKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params: SearchIngestionKeysParams,
options?: {

View File

@@ -14,8 +14,7 @@ import type {
} from 'react-query';
import { useQuery } from 'react-query';
import type { ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
GetGlobalConfig200,
RenderErrorResponseDTO,
@@ -38,12 +37,12 @@ export const getGlobalConfig = (signal?: AbortSignal) => {
};
export const getGetGlobalConfigQueryKey = () => {
return [`/api/v1/global/config`] as const;
return ['getGlobalConfig'] as const;
};
export const getGetGlobalConfigQueryOptions = <
TData = Awaited<ReturnType<typeof getGlobalConfig>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getGlobalConfig>>,
@@ -69,7 +68,7 @@ export const getGetGlobalConfigQueryOptions = <
export type GetGlobalConfigQueryResult = NonNullable<
Awaited<ReturnType<typeof getGlobalConfig>>
>;
export type GetGlobalConfigQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetGlobalConfigQueryError = RenderErrorResponseDTO;
/**
* @summary Get global config
@@ -77,7 +76,7 @@ export type GetGlobalConfigQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetGlobalConfig<
TData = Awaited<ReturnType<typeof getGlobalConfig>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getGlobalConfig>>,

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
ListPromotedAndIndexedPaths200,
PromotetypesPromotePathDTO,
@@ -42,12 +41,12 @@ export const listPromotedAndIndexedPaths = (signal?: AbortSignal) => {
};
export const getListPromotedAndIndexedPathsQueryKey = () => {
return [`/api/v1/logs/promote_paths`] as const;
return ['listPromotedAndIndexedPaths'] as const;
};
export const getListPromotedAndIndexedPathsQueryOptions = <
TData = Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
@@ -74,7 +73,7 @@ export const getListPromotedAndIndexedPathsQueryOptions = <
export type ListPromotedAndIndexedPathsQueryResult = NonNullable<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>
>;
export type ListPromotedAndIndexedPathsQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListPromotedAndIndexedPathsQueryError = RenderErrorResponseDTO;
/**
* @summary Promote and index paths
@@ -82,7 +81,7 @@ export type ListPromotedAndIndexedPathsQueryError = ErrorType<RenderErrorRespons
export function useListPromotedAndIndexedPaths<
TData = Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listPromotedAndIndexedPaths>>,
@@ -121,9 +120,7 @@ export const invalidateListPromotedAndIndexedPaths = async (
* @summary Promote and index paths
*/
export const handlePromoteAndIndexPaths = (
promotetypesPromotePathDTONull: BodyType<
PromotetypesPromotePathDTO[] | null
> | null,
promotetypesPromotePathDTONull: PromotetypesPromotePathDTO[] | null,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
@@ -136,19 +133,19 @@ export const handlePromoteAndIndexPaths = (
};
export const getHandlePromoteAndIndexPathsMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: BodyType<PromotetypesPromotePathDTO[] | null> },
{ data: PromotetypesPromotePathDTO[] | null },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: BodyType<PromotetypesPromotePathDTO[] | null> },
{ data: PromotetypesPromotePathDTO[] | null },
TContext
> => {
const mutationKey = ['handlePromoteAndIndexPaths'];
@@ -162,7 +159,7 @@ export const getHandlePromoteAndIndexPathsMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
{ data: BodyType<PromotetypesPromotePathDTO[] | null> }
{ data: PromotetypesPromotePathDTO[] | null }
> = (props) => {
const { data } = props ?? {};
@@ -175,28 +172,28 @@ export const getHandlePromoteAndIndexPathsMutationOptions = <
export type HandlePromoteAndIndexPathsMutationResult = NonNullable<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>
>;
export type HandlePromoteAndIndexPathsMutationBody = BodyType<
PromotetypesPromotePathDTO[] | null
>;
export type HandlePromoteAndIndexPathsMutationError = ErrorType<RenderErrorResponseDTO>;
export type HandlePromoteAndIndexPathsMutationBody =
| PromotetypesPromotePathDTO[]
| null;
export type HandlePromoteAndIndexPathsMutationError = RenderErrorResponseDTO;
/**
* @summary Promote and index paths
*/
export const useHandlePromoteAndIndexPaths = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: BodyType<PromotetypesPromotePathDTO[] | null> },
{ data: PromotetypesPromotePathDTO[] | null },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof handlePromoteAndIndexPaths>>,
TError,
{ data: BodyType<PromotetypesPromotePathDTO[] | null> },
{ data: PromotetypesPromotePathDTO[] | null },
TContext
> => {
const mutationOptions = getHandlePromoteAndIndexPathsMutationOptions(options);

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
GetMetricAlerts200,
GetMetricAlertsPathParameters,
@@ -63,12 +62,12 @@ export const listMetrics = (
};
export const getListMetricsQueryKey = (params?: ListMetricsParams) => {
return [`/api/v2/metrics`, ...(params ? [params] : [])] as const;
return ['listMetrics', ...(params ? [params] : [])] as const;
};
export const getListMetricsQueryOptions = <
TData = Awaited<ReturnType<typeof listMetrics>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: ListMetricsParams,
options?: {
@@ -97,7 +96,7 @@ export const getListMetricsQueryOptions = <
export type ListMetricsQueryResult = NonNullable<
Awaited<ReturnType<typeof listMetrics>>
>;
export type ListMetricsQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListMetricsQueryError = RenderErrorResponseDTO;
/**
* @summary List metric names
@@ -105,7 +104,7 @@ export type ListMetricsQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListMetrics<
TData = Awaited<ReturnType<typeof listMetrics>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
params?: ListMetricsParams,
options?: {
@@ -161,12 +160,12 @@ export const getMetricAlerts = (
export const getGetMetricAlertsQueryKey = ({
metricName,
}: GetMetricAlertsPathParameters) => {
return [`/api/v2/metrics/${metricName}/alerts`] as const;
return ['getMetricAlerts'] as const;
};
export const getGetMetricAlertsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricAlertsPathParameters,
options?: {
@@ -201,7 +200,7 @@ export const getGetMetricAlertsQueryOptions = <
export type GetMetricAlertsQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricAlerts>>
>;
export type GetMetricAlertsQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetMetricAlertsQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric alerts
@@ -209,7 +208,7 @@ export type GetMetricAlertsQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetMetricAlerts<
TData = Awaited<ReturnType<typeof getMetricAlerts>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricAlertsPathParameters,
options?: {
@@ -268,15 +267,12 @@ export const getGetMetricAttributesQueryKey = (
{ metricName }: GetMetricAttributesPathParameters,
params?: GetMetricAttributesParams,
) => {
return [
`/api/v2/metrics/${metricName}/attributes`,
...(params ? [params] : []),
] as const;
return ['getMetricAttributes', ...(params ? [params] : [])] as const;
};
export const getGetMetricAttributesQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricAttributes>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricAttributesPathParameters,
params?: GetMetricAttributesParams,
@@ -313,7 +309,7 @@ export const getGetMetricAttributesQueryOptions = <
export type GetMetricAttributesQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricAttributes>>
>;
export type GetMetricAttributesQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetMetricAttributesQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric attributes
@@ -321,7 +317,7 @@ export type GetMetricAttributesQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetMetricAttributes<
TData = Awaited<ReturnType<typeof getMetricAttributes>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricAttributesPathParameters,
params?: GetMetricAttributesParams,
@@ -383,12 +379,12 @@ export const getMetricDashboards = (
export const getGetMetricDashboardsQueryKey = ({
metricName,
}: GetMetricDashboardsPathParameters) => {
return [`/api/v2/metrics/${metricName}/dashboards`] as const;
return ['getMetricDashboards'] as const;
};
export const getGetMetricDashboardsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricDashboardsPathParameters,
options?: {
@@ -423,7 +419,7 @@ export const getGetMetricDashboardsQueryOptions = <
export type GetMetricDashboardsQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricDashboards>>
>;
export type GetMetricDashboardsQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetMetricDashboardsQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric dashboards
@@ -431,7 +427,7 @@ export type GetMetricDashboardsQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetMetricDashboards<
TData = Awaited<ReturnType<typeof getMetricDashboards>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricDashboardsPathParameters,
options?: {
@@ -490,12 +486,12 @@ export const getMetricHighlights = (
export const getGetMetricHighlightsQueryKey = ({
metricName,
}: GetMetricHighlightsPathParameters) => {
return [`/api/v2/metrics/${metricName}/highlights`] as const;
return ['getMetricHighlights'] as const;
};
export const getGetMetricHighlightsQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricHighlightsPathParameters,
options?: {
@@ -530,7 +526,7 @@ export const getGetMetricHighlightsQueryOptions = <
export type GetMetricHighlightsQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricHighlights>>
>;
export type GetMetricHighlightsQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetMetricHighlightsQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric highlights
@@ -538,7 +534,7 @@ export type GetMetricHighlightsQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetMetricHighlights<
TData = Awaited<ReturnType<typeof getMetricHighlights>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricHighlightsPathParameters,
options?: {
@@ -597,12 +593,12 @@ export const getMetricMetadata = (
export const getGetMetricMetadataQueryKey = ({
metricName,
}: GetMetricMetadataPathParameters) => {
return [`/api/v2/metrics/${metricName}/metadata`] as const;
return ['getMetricMetadata'] as const;
};
export const getGetMetricMetadataQueryOptions = <
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricMetadataPathParameters,
options?: {
@@ -637,7 +633,7 @@ export const getGetMetricMetadataQueryOptions = <
export type GetMetricMetadataQueryResult = NonNullable<
Awaited<ReturnType<typeof getMetricMetadata>>
>;
export type GetMetricMetadataQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetMetricMetadataQueryError = RenderErrorResponseDTO;
/**
* @summary Get metric metadata
@@ -645,7 +641,7 @@ export type GetMetricMetadataQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetMetricMetadata<
TData = Awaited<ReturnType<typeof getMetricMetadata>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ metricName }: GetMetricMetadataPathParameters,
options?: {
@@ -689,7 +685,7 @@ export const invalidateGetMetricMetadata = async (
*/
export const updateMetricMetadata = (
{ metricName }: UpdateMetricMetadataPathParameters,
metricsexplorertypesUpdateMetricMetadataRequestDTO: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>,
metricsexplorertypesUpdateMetricMetadataRequestDTO: MetricsexplorertypesUpdateMetricMetadataRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<string>({
@@ -702,7 +698,7 @@ export const updateMetricMetadata = (
};
export const getUpdateMetricMetadataMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -710,7 +706,7 @@ export const getUpdateMetricMetadataMutationOptions = <
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
>;
@@ -719,7 +715,7 @@ export const getUpdateMetricMetadataMutationOptions = <
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
> => {
@@ -736,7 +732,7 @@ export const getUpdateMetricMetadataMutationOptions = <
Awaited<ReturnType<typeof updateMetricMetadata>>,
{
pathParams: UpdateMetricMetadataPathParameters;
data: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -750,14 +746,14 @@ export const getUpdateMetricMetadataMutationOptions = <
export type UpdateMetricMetadataMutationResult = NonNullable<
Awaited<ReturnType<typeof updateMetricMetadata>>
>;
export type UpdateMetricMetadataMutationBody = BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>;
export type UpdateMetricMetadataMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateMetricMetadataMutationBody = MetricsexplorertypesUpdateMetricMetadataRequestDTO;
export type UpdateMetricMetadataMutationError = RenderErrorResponseDTO;
/**
* @summary Update metric metadata
*/
export const useUpdateMetricMetadata = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -765,7 +761,7 @@ export const useUpdateMetricMetadata = <
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
>;
@@ -774,7 +770,7 @@ export const useUpdateMetricMetadata = <
TError,
{
pathParams: UpdateMetricMetadataPathParameters;
data: BodyType<MetricsexplorertypesUpdateMetricMetadataRequestDTO>;
data: MetricsexplorertypesUpdateMetricMetadataRequestDTO;
},
TContext
> => {
@@ -787,7 +783,7 @@ export const useUpdateMetricMetadata = <
* @summary Get metrics statistics
*/
export const getMetricsStats = (
metricsexplorertypesStatsRequestDTO: BodyType<MetricsexplorertypesStatsRequestDTO>,
metricsexplorertypesStatsRequestDTO: MetricsexplorertypesStatsRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricsStats200>({
@@ -800,19 +796,19 @@ export const getMetricsStats = (
};
export const getGetMetricsStatsMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: BodyType<MetricsexplorertypesStatsRequestDTO> },
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: BodyType<MetricsexplorertypesStatsRequestDTO> },
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
> => {
const mutationKey = ['getMetricsStats'];
@@ -826,7 +822,7 @@ export const getGetMetricsStatsMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof getMetricsStats>>,
{ data: BodyType<MetricsexplorertypesStatsRequestDTO> }
{ data: MetricsexplorertypesStatsRequestDTO }
> = (props) => {
const { data } = props ?? {};
@@ -839,26 +835,26 @@ export const getGetMetricsStatsMutationOptions = <
export type GetMetricsStatsMutationResult = NonNullable<
Awaited<ReturnType<typeof getMetricsStats>>
>;
export type GetMetricsStatsMutationBody = BodyType<MetricsexplorertypesStatsRequestDTO>;
export type GetMetricsStatsMutationError = ErrorType<RenderErrorResponseDTO>;
export type GetMetricsStatsMutationBody = MetricsexplorertypesStatsRequestDTO;
export type GetMetricsStatsMutationError = RenderErrorResponseDTO;
/**
* @summary Get metrics statistics
*/
export const useGetMetricsStats = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: BodyType<MetricsexplorertypesStatsRequestDTO> },
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof getMetricsStats>>,
TError,
{ data: BodyType<MetricsexplorertypesStatsRequestDTO> },
{ data: MetricsexplorertypesStatsRequestDTO },
TContext
> => {
const mutationOptions = getGetMetricsStatsMutationOptions(options);
@@ -870,7 +866,7 @@ export const useGetMetricsStats = <
* @summary Get metrics treemap
*/
export const getMetricsTreemap = (
metricsexplorertypesTreemapRequestDTO: BodyType<MetricsexplorertypesTreemapRequestDTO>,
metricsexplorertypesTreemapRequestDTO: MetricsexplorertypesTreemapRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<GetMetricsTreemap200>({
@@ -883,19 +879,19 @@ export const getMetricsTreemap = (
};
export const getGetMetricsTreemapMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: BodyType<MetricsexplorertypesTreemapRequestDTO> },
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: BodyType<MetricsexplorertypesTreemapRequestDTO> },
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
> => {
const mutationKey = ['getMetricsTreemap'];
@@ -909,7 +905,7 @@ export const getGetMetricsTreemapMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof getMetricsTreemap>>,
{ data: BodyType<MetricsexplorertypesTreemapRequestDTO> }
{ data: MetricsexplorertypesTreemapRequestDTO }
> = (props) => {
const { data } = props ?? {};
@@ -922,26 +918,26 @@ export const getGetMetricsTreemapMutationOptions = <
export type GetMetricsTreemapMutationResult = NonNullable<
Awaited<ReturnType<typeof getMetricsTreemap>>
>;
export type GetMetricsTreemapMutationBody = BodyType<MetricsexplorertypesTreemapRequestDTO>;
export type GetMetricsTreemapMutationError = ErrorType<RenderErrorResponseDTO>;
export type GetMetricsTreemapMutationBody = MetricsexplorertypesTreemapRequestDTO;
export type GetMetricsTreemapMutationError = RenderErrorResponseDTO;
/**
* @summary Get metrics treemap
*/
export const useGetMetricsTreemap = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: BodyType<MetricsexplorertypesTreemapRequestDTO> },
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof getMetricsTreemap>>,
TError,
{ data: BodyType<MetricsexplorertypesTreemapRequestDTO> },
{ data: MetricsexplorertypesTreemapRequestDTO },
TContext
> => {
const mutationOptions = getGetMetricsTreemapMutationOptions(options);

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
GetMyOrganization200,
RenderErrorResponseDTO,
@@ -42,12 +41,12 @@ export const getMyOrganization = (signal?: AbortSignal) => {
};
export const getGetMyOrganizationQueryKey = () => {
return [`/api/v2/orgs/me`] as const;
return ['getMyOrganization'] as const;
};
export const getGetMyOrganizationQueryOptions = <
TData = Awaited<ReturnType<typeof getMyOrganization>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMyOrganization>>,
@@ -73,7 +72,7 @@ export const getGetMyOrganizationQueryOptions = <
export type GetMyOrganizationQueryResult = NonNullable<
Awaited<ReturnType<typeof getMyOrganization>>
>;
export type GetMyOrganizationQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetMyOrganizationQueryError = RenderErrorResponseDTO;
/**
* @summary Get my organization
@@ -81,7 +80,7 @@ export type GetMyOrganizationQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetMyOrganization<
TData = Awaited<ReturnType<typeof getMyOrganization>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getMyOrganization>>,
@@ -120,7 +119,7 @@ export const invalidateGetMyOrganization = async (
* @summary Update my organization
*/
export const updateMyOrganization = (
typesOrganizationDTO: BodyType<TypesOrganizationDTO>,
typesOrganizationDTO: TypesOrganizationDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/orgs/me`,
@@ -131,19 +130,19 @@ export const updateMyOrganization = (
};
export const getUpdateMyOrganizationMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: BodyType<TypesOrganizationDTO> },
{ data: TypesOrganizationDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: BodyType<TypesOrganizationDTO> },
{ data: TypesOrganizationDTO },
TContext
> => {
const mutationKey = ['updateMyOrganization'];
@@ -157,7 +156,7 @@ export const getUpdateMyOrganizationMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateMyOrganization>>,
{ data: BodyType<TypesOrganizationDTO> }
{ data: TypesOrganizationDTO }
> = (props) => {
const { data } = props ?? {};
@@ -170,26 +169,26 @@ export const getUpdateMyOrganizationMutationOptions = <
export type UpdateMyOrganizationMutationResult = NonNullable<
Awaited<ReturnType<typeof updateMyOrganization>>
>;
export type UpdateMyOrganizationMutationBody = BodyType<TypesOrganizationDTO>;
export type UpdateMyOrganizationMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateMyOrganizationMutationBody = TypesOrganizationDTO;
export type UpdateMyOrganizationMutationError = RenderErrorResponseDTO;
/**
* @summary Update my organization
*/
export const useUpdateMyOrganization = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: BodyType<TypesOrganizationDTO> },
{ data: TypesOrganizationDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateMyOrganization>>,
TError,
{ data: BodyType<TypesOrganizationDTO> },
{ data: TypesOrganizationDTO },
TContext
> => {
const mutationOptions = getUpdateMyOrganizationMutationOptions(options);

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
GetOrgPreference200,
GetOrgPreferencePathParameters,
@@ -49,12 +48,12 @@ export const listOrgPreferences = (signal?: AbortSignal) => {
};
export const getListOrgPreferencesQueryKey = () => {
return [`/api/v1/org/preferences`] as const;
return ['listOrgPreferences'] as const;
};
export const getListOrgPreferencesQueryOptions = <
TData = Awaited<ReturnType<typeof listOrgPreferences>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listOrgPreferences>>,
@@ -80,7 +79,7 @@ export const getListOrgPreferencesQueryOptions = <
export type ListOrgPreferencesQueryResult = NonNullable<
Awaited<ReturnType<typeof listOrgPreferences>>
>;
export type ListOrgPreferencesQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListOrgPreferencesQueryError = RenderErrorResponseDTO;
/**
* @summary List org preferences
@@ -88,7 +87,7 @@ export type ListOrgPreferencesQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListOrgPreferences<
TData = Awaited<ReturnType<typeof listOrgPreferences>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listOrgPreferences>>,
@@ -140,12 +139,12 @@ export const getOrgPreference = (
export const getGetOrgPreferenceQueryKey = ({
name,
}: GetOrgPreferencePathParameters) => {
return [`/api/v1/org/preferences/${name}`] as const;
return ['getOrgPreference'] as const;
};
export const getGetOrgPreferenceQueryOptions = <
TData = Awaited<ReturnType<typeof getOrgPreference>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ name }: GetOrgPreferencePathParameters,
options?: {
@@ -180,7 +179,7 @@ export const getGetOrgPreferenceQueryOptions = <
export type GetOrgPreferenceQueryResult = NonNullable<
Awaited<ReturnType<typeof getOrgPreference>>
>;
export type GetOrgPreferenceQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetOrgPreferenceQueryError = RenderErrorResponseDTO;
/**
* @summary Get org preference
@@ -188,7 +187,7 @@ export type GetOrgPreferenceQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetOrgPreference<
TData = Awaited<ReturnType<typeof getOrgPreference>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ name }: GetOrgPreferencePathParameters,
options?: {
@@ -232,7 +231,7 @@ export const invalidateGetOrgPreference = async (
*/
export const updateOrgPreference = (
{ name }: UpdateOrgPreferencePathParameters,
preferencetypesUpdatablePreferenceDTO: BodyType<PreferencetypesUpdatablePreferenceDTO>,
preferencetypesUpdatablePreferenceDTO: PreferencetypesUpdatablePreferenceDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/org/preferences/${name}`,
@@ -243,7 +242,7 @@ export const updateOrgPreference = (
};
export const getUpdateOrgPreferenceMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -251,7 +250,7 @@ export const getUpdateOrgPreferenceMutationOptions = <
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
@@ -260,7 +259,7 @@ export const getUpdateOrgPreferenceMutationOptions = <
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {
@@ -277,7 +276,7 @@ export const getUpdateOrgPreferenceMutationOptions = <
Awaited<ReturnType<typeof updateOrgPreference>>,
{
pathParams: UpdateOrgPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -291,14 +290,14 @@ export const getUpdateOrgPreferenceMutationOptions = <
export type UpdateOrgPreferenceMutationResult = NonNullable<
Awaited<ReturnType<typeof updateOrgPreference>>
>;
export type UpdateOrgPreferenceMutationBody = BodyType<PreferencetypesUpdatablePreferenceDTO>;
export type UpdateOrgPreferenceMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateOrgPreferenceMutationBody = PreferencetypesUpdatablePreferenceDTO;
export type UpdateOrgPreferenceMutationError = RenderErrorResponseDTO;
/**
* @summary Update org preference
*/
export const useUpdateOrgPreference = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -306,7 +305,7 @@ export const useUpdateOrgPreference = <
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
@@ -315,7 +314,7 @@ export const useUpdateOrgPreference = <
TError,
{
pathParams: UpdateOrgPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {
@@ -336,12 +335,12 @@ export const listUserPreferences = (signal?: AbortSignal) => {
};
export const getListUserPreferencesQueryKey = () => {
return [`/api/v1/user/preferences`] as const;
return ['listUserPreferences'] as const;
};
export const getListUserPreferencesQueryOptions = <
TData = Awaited<ReturnType<typeof listUserPreferences>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listUserPreferences>>,
@@ -367,7 +366,7 @@ export const getListUserPreferencesQueryOptions = <
export type ListUserPreferencesQueryResult = NonNullable<
Awaited<ReturnType<typeof listUserPreferences>>
>;
export type ListUserPreferencesQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListUserPreferencesQueryError = RenderErrorResponseDTO;
/**
* @summary List user preferences
@@ -375,7 +374,7 @@ export type ListUserPreferencesQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListUserPreferences<
TData = Awaited<ReturnType<typeof listUserPreferences>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listUserPreferences>>,
@@ -427,12 +426,12 @@ export const getUserPreference = (
export const getGetUserPreferenceQueryKey = ({
name,
}: GetUserPreferencePathParameters) => {
return [`/api/v1/user/preferences/${name}`] as const;
return ['getUserPreference'] as const;
};
export const getGetUserPreferenceQueryOptions = <
TData = Awaited<ReturnType<typeof getUserPreference>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ name }: GetUserPreferencePathParameters,
options?: {
@@ -467,7 +466,7 @@ export const getGetUserPreferenceQueryOptions = <
export type GetUserPreferenceQueryResult = NonNullable<
Awaited<ReturnType<typeof getUserPreference>>
>;
export type GetUserPreferenceQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetUserPreferenceQueryError = RenderErrorResponseDTO;
/**
* @summary Get user preference
@@ -475,7 +474,7 @@ export type GetUserPreferenceQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetUserPreference<
TData = Awaited<ReturnType<typeof getUserPreference>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ name }: GetUserPreferencePathParameters,
options?: {
@@ -519,7 +518,7 @@ export const invalidateGetUserPreference = async (
*/
export const updateUserPreference = (
{ name }: UpdateUserPreferencePathParameters,
preferencetypesUpdatablePreferenceDTO: BodyType<PreferencetypesUpdatablePreferenceDTO>,
preferencetypesUpdatablePreferenceDTO: PreferencetypesUpdatablePreferenceDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v1/user/preferences/${name}`,
@@ -530,7 +529,7 @@ export const updateUserPreference = (
};
export const getUpdateUserPreferenceMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -538,7 +537,7 @@ export const getUpdateUserPreferenceMutationOptions = <
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
@@ -547,7 +546,7 @@ export const getUpdateUserPreferenceMutationOptions = <
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {
@@ -564,7 +563,7 @@ export const getUpdateUserPreferenceMutationOptions = <
Awaited<ReturnType<typeof updateUserPreference>>,
{
pathParams: UpdateUserPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -578,14 +577,14 @@ export const getUpdateUserPreferenceMutationOptions = <
export type UpdateUserPreferenceMutationResult = NonNullable<
Awaited<ReturnType<typeof updateUserPreference>>
>;
export type UpdateUserPreferenceMutationBody = BodyType<PreferencetypesUpdatablePreferenceDTO>;
export type UpdateUserPreferenceMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateUserPreferenceMutationBody = PreferencetypesUpdatablePreferenceDTO;
export type UpdateUserPreferenceMutationError = RenderErrorResponseDTO;
/**
* @summary Update user preference
*/
export const useUpdateUserPreference = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -593,7 +592,7 @@ export const useUpdateUserPreference = <
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
>;
@@ -602,7 +601,7 @@ export const useUpdateUserPreference = <
TError,
{
pathParams: UpdateUserPreferencePathParameters;
data: BodyType<PreferencetypesUpdatablePreferenceDTO>;
data: PreferencetypesUpdatablePreferenceDTO;
},
TContext
> => {

View File

@@ -11,8 +11,7 @@ import type {
} from 'react-query';
import { useMutation } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
Querybuildertypesv5QueryRangeRequestDTO,
QueryRangeV5200,
@@ -29,7 +28,7 @@ type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
* @summary Query range
*/
export const queryRangeV5 = (
querybuildertypesv5QueryRangeRequestDTO: BodyType<Querybuildertypesv5QueryRangeRequestDTO>,
querybuildertypesv5QueryRangeRequestDTO: Querybuildertypesv5QueryRangeRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<QueryRangeV5200>({
@@ -42,19 +41,19 @@ export const queryRangeV5 = (
};
export const getQueryRangeV5MutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof queryRangeV5>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof queryRangeV5>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
> => {
const mutationKey = ['queryRangeV5'];
@@ -68,7 +67,7 @@ export const getQueryRangeV5MutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof queryRangeV5>>,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> }
{ data: Querybuildertypesv5QueryRangeRequestDTO }
> = (props) => {
const { data } = props ?? {};
@@ -81,26 +80,26 @@ export const getQueryRangeV5MutationOptions = <
export type QueryRangeV5MutationResult = NonNullable<
Awaited<ReturnType<typeof queryRangeV5>>
>;
export type QueryRangeV5MutationBody = BodyType<Querybuildertypesv5QueryRangeRequestDTO>;
export type QueryRangeV5MutationError = ErrorType<RenderErrorResponseDTO>;
export type QueryRangeV5MutationBody = Querybuildertypesv5QueryRangeRequestDTO;
export type QueryRangeV5MutationError = RenderErrorResponseDTO;
/**
* @summary Query range
*/
export const useQueryRangeV5 = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof queryRangeV5>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof queryRangeV5>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
> => {
const mutationOptions = getQueryRangeV5MutationOptions(options);
@@ -112,7 +111,7 @@ export const useQueryRangeV5 = <
* @summary Replace variables
*/
export const replaceVariables = (
querybuildertypesv5QueryRangeRequestDTO: BodyType<Querybuildertypesv5QueryRangeRequestDTO>,
querybuildertypesv5QueryRangeRequestDTO: Querybuildertypesv5QueryRangeRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<ReplaceVariables200>({
@@ -125,19 +124,19 @@ export const replaceVariables = (
};
export const getReplaceVariablesMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof replaceVariables>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof replaceVariables>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
> => {
const mutationKey = ['replaceVariables'];
@@ -151,7 +150,7 @@ export const getReplaceVariablesMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof replaceVariables>>,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> }
{ data: Querybuildertypesv5QueryRangeRequestDTO }
> = (props) => {
const { data } = props ?? {};
@@ -164,26 +163,26 @@ export const getReplaceVariablesMutationOptions = <
export type ReplaceVariablesMutationResult = NonNullable<
Awaited<ReturnType<typeof replaceVariables>>
>;
export type ReplaceVariablesMutationBody = BodyType<Querybuildertypesv5QueryRangeRequestDTO>;
export type ReplaceVariablesMutationError = ErrorType<RenderErrorResponseDTO>;
export type ReplaceVariablesMutationBody = Querybuildertypesv5QueryRangeRequestDTO;
export type ReplaceVariablesMutationError = RenderErrorResponseDTO;
/**
* @summary Replace variables
*/
export const useReplaceVariables = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof replaceVariables>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof replaceVariables>>,
TError,
{ data: BodyType<Querybuildertypesv5QueryRangeRequestDTO> },
{ data: Querybuildertypesv5QueryRangeRequestDTO },
TContext
> => {
const mutationOptions = getReplaceVariablesMutationOptions(options);

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
CreateRole201,
DeleteRolePathParameters,
@@ -53,12 +52,12 @@ export const listRoles = (signal?: AbortSignal) => {
};
export const getListRolesQueryKey = () => {
return [`/api/v1/roles`] as const;
return ['listRoles'] as const;
};
export const getListRolesQueryOptions = <
TData = Awaited<ReturnType<typeof listRoles>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
}) => {
@@ -80,7 +79,7 @@ export const getListRolesQueryOptions = <
export type ListRolesQueryResult = NonNullable<
Awaited<ReturnType<typeof listRoles>>
>;
export type ListRolesQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListRolesQueryError = RenderErrorResponseDTO;
/**
* @summary List roles
@@ -88,7 +87,7 @@ export type ListRolesQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListRoles<
TData = Awaited<ReturnType<typeof listRoles>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listRoles>>, TError, TData>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
@@ -123,7 +122,7 @@ export const invalidateListRoles = async (
* @summary Create role
*/
export const createRole = (
roletypesPostableRoleDTO: BodyType<RoletypesPostableRoleDTO>,
roletypesPostableRoleDTO: RoletypesPostableRoleDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateRole201>({
@@ -136,19 +135,19 @@ export const createRole = (
};
export const getCreateRoleMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createRole>>,
TError,
{ data: BodyType<RoletypesPostableRoleDTO> },
{ data: RoletypesPostableRoleDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createRole>>,
TError,
{ data: BodyType<RoletypesPostableRoleDTO> },
{ data: RoletypesPostableRoleDTO },
TContext
> => {
const mutationKey = ['createRole'];
@@ -162,7 +161,7 @@ export const getCreateRoleMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createRole>>,
{ data: BodyType<RoletypesPostableRoleDTO> }
{ data: RoletypesPostableRoleDTO }
> = (props) => {
const { data } = props ?? {};
@@ -175,26 +174,26 @@ export const getCreateRoleMutationOptions = <
export type CreateRoleMutationResult = NonNullable<
Awaited<ReturnType<typeof createRole>>
>;
export type CreateRoleMutationBody = BodyType<RoletypesPostableRoleDTO>;
export type CreateRoleMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateRoleMutationBody = RoletypesPostableRoleDTO;
export type CreateRoleMutationError = RenderErrorResponseDTO;
/**
* @summary Create role
*/
export const useCreateRole = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createRole>>,
TError,
{ data: BodyType<RoletypesPostableRoleDTO> },
{ data: RoletypesPostableRoleDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createRole>>,
TError,
{ data: BodyType<RoletypesPostableRoleDTO> },
{ data: RoletypesPostableRoleDTO },
TContext
> => {
const mutationOptions = getCreateRoleMutationOptions(options);
@@ -213,7 +212,7 @@ export const deleteRole = ({ id }: DeleteRolePathParameters) => {
};
export const getDeleteRoleMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -253,13 +252,13 @@ export type DeleteRoleMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteRole>>
>;
export type DeleteRoleMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeleteRoleMutationError = RenderErrorResponseDTO;
/**
* @summary Delete role
*/
export const useDeleteRole = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -294,12 +293,12 @@ export const getRole = (
};
export const getGetRoleQueryKey = ({ id }: GetRolePathParameters) => {
return [`/api/v1/roles/${id}`] as const;
return ['getRole'] as const;
};
export const getGetRoleQueryOptions = <
TData = Awaited<ReturnType<typeof getRole>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetRolePathParameters,
options?: {
@@ -327,7 +326,7 @@ export const getGetRoleQueryOptions = <
export type GetRoleQueryResult = NonNullable<
Awaited<ReturnType<typeof getRole>>
>;
export type GetRoleQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetRoleQueryError = RenderErrorResponseDTO;
/**
* @summary Get role
@@ -335,7 +334,7 @@ export type GetRoleQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetRole<
TData = Awaited<ReturnType<typeof getRole>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetRolePathParameters,
options?: {
@@ -375,7 +374,7 @@ export const invalidateGetRole = async (
*/
export const patchRole = (
{ id }: PatchRolePathParameters,
roletypesPatchableRoleDTO: BodyType<RoletypesPatchableRoleDTO>,
roletypesPatchableRoleDTO: RoletypesPatchableRoleDTO,
) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/roles/${id}`,
@@ -386,25 +385,19 @@ export const patchRole = (
};
export const getPatchRoleMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof patchRole>>,
TError,
{
pathParams: PatchRolePathParameters;
data: BodyType<RoletypesPatchableRoleDTO>;
},
{ pathParams: PatchRolePathParameters; data: RoletypesPatchableRoleDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof patchRole>>,
TError,
{
pathParams: PatchRolePathParameters;
data: BodyType<RoletypesPatchableRoleDTO>;
},
{ pathParams: PatchRolePathParameters; data: RoletypesPatchableRoleDTO },
TContext
> => {
const mutationKey = ['patchRole'];
@@ -418,10 +411,7 @@ export const getPatchRoleMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof patchRole>>,
{
pathParams: PatchRolePathParameters;
data: BodyType<RoletypesPatchableRoleDTO>;
}
{ pathParams: PatchRolePathParameters; data: RoletypesPatchableRoleDTO }
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -434,32 +424,26 @@ export const getPatchRoleMutationOptions = <
export type PatchRoleMutationResult = NonNullable<
Awaited<ReturnType<typeof patchRole>>
>;
export type PatchRoleMutationBody = BodyType<RoletypesPatchableRoleDTO>;
export type PatchRoleMutationError = ErrorType<RenderErrorResponseDTO>;
export type PatchRoleMutationBody = RoletypesPatchableRoleDTO;
export type PatchRoleMutationError = RenderErrorResponseDTO;
/**
* @summary Patch role
*/
export const usePatchRole = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof patchRole>>,
TError,
{
pathParams: PatchRolePathParameters;
data: BodyType<RoletypesPatchableRoleDTO>;
},
{ pathParams: PatchRolePathParameters; data: RoletypesPatchableRoleDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof patchRole>>,
TError,
{
pathParams: PatchRolePathParameters;
data: BodyType<RoletypesPatchableRoleDTO>;
},
{ pathParams: PatchRolePathParameters; data: RoletypesPatchableRoleDTO },
TContext
> => {
const mutationOptions = getPatchRoleMutationOptions(options);
@@ -485,12 +469,12 @@ export const getGetObjectsQueryKey = ({
id,
relation,
}: GetObjectsPathParameters) => {
return [`/api/v1/roles/${id}/relation/${relation}/objects`] as const;
return ['getObjects'] as const;
};
export const getGetObjectsQueryOptions = <
TData = Awaited<ReturnType<typeof getObjects>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id, relation }: GetObjectsPathParameters,
options?: {
@@ -523,7 +507,7 @@ export const getGetObjectsQueryOptions = <
export type GetObjectsQueryResult = NonNullable<
Awaited<ReturnType<typeof getObjects>>
>;
export type GetObjectsQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetObjectsQueryError = RenderErrorResponseDTO;
/**
* @summary Get objects for a role by relation
@@ -531,7 +515,7 @@ export type GetObjectsQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetObjects<
TData = Awaited<ReturnType<typeof getObjects>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id, relation }: GetObjectsPathParameters,
options?: {
@@ -575,7 +559,7 @@ export const invalidateGetObjects = async (
*/
export const patchObjects = (
{ id, relation }: PatchObjectsPathParameters,
roletypesPatchableObjectsDTO: BodyType<RoletypesPatchableObjectsDTO>,
roletypesPatchableObjectsDTO: RoletypesPatchableObjectsDTO,
) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/roles/${id}/relation/${relation}/objects`,
@@ -586,7 +570,7 @@ export const patchObjects = (
};
export const getPatchObjectsMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -594,17 +578,14 @@ export const getPatchObjectsMutationOptions = <
TError,
{
pathParams: PatchObjectsPathParameters;
data: BodyType<RoletypesPatchableObjectsDTO>;
data: RoletypesPatchableObjectsDTO;
},
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof patchObjects>>,
TError,
{
pathParams: PatchObjectsPathParameters;
data: BodyType<RoletypesPatchableObjectsDTO>;
},
{ pathParams: PatchObjectsPathParameters; data: RoletypesPatchableObjectsDTO },
TContext
> => {
const mutationKey = ['patchObjects'];
@@ -618,10 +599,7 @@ export const getPatchObjectsMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof patchObjects>>,
{
pathParams: PatchObjectsPathParameters;
data: BodyType<RoletypesPatchableObjectsDTO>;
}
{ pathParams: PatchObjectsPathParameters; data: RoletypesPatchableObjectsDTO }
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -634,14 +612,14 @@ export const getPatchObjectsMutationOptions = <
export type PatchObjectsMutationResult = NonNullable<
Awaited<ReturnType<typeof patchObjects>>
>;
export type PatchObjectsMutationBody = BodyType<RoletypesPatchableObjectsDTO>;
export type PatchObjectsMutationError = ErrorType<RenderErrorResponseDTO>;
export type PatchObjectsMutationBody = RoletypesPatchableObjectsDTO;
export type PatchObjectsMutationError = RenderErrorResponseDTO;
/**
* @summary Patch objects for a role by relation
*/
export const usePatchObjects = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -649,17 +627,14 @@ export const usePatchObjects = <
TError,
{
pathParams: PatchObjectsPathParameters;
data: BodyType<RoletypesPatchableObjectsDTO>;
data: RoletypesPatchableObjectsDTO;
},
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof patchObjects>>,
TError,
{
pathParams: PatchObjectsPathParameters;
data: BodyType<RoletypesPatchableObjectsDTO>;
},
{ pathParams: PatchObjectsPathParameters; data: RoletypesPatchableObjectsDTO },
TContext
> => {
const mutationOptions = getPatchObjectsMutationOptions(options);
@@ -679,12 +654,12 @@ export const getResources = (signal?: AbortSignal) => {
};
export const getGetResourcesQueryKey = () => {
return [`/api/v1/roles/resources`] as const;
return ['getResources'] as const;
};
export const getGetResourcesQueryOptions = <
TData = Awaited<ReturnType<typeof getResources>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getResources>>,
@@ -710,7 +685,7 @@ export const getGetResourcesQueryOptions = <
export type GetResourcesQueryResult = NonNullable<
Awaited<ReturnType<typeof getResources>>
>;
export type GetResourcesQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetResourcesQueryError = RenderErrorResponseDTO;
/**
* @summary Get resources
@@ -718,7 +693,7 @@ export type GetResourcesQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetResources<
TData = Awaited<ReturnType<typeof getResources>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getResources>>,

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
AuthtypesPostableEmailPasswordSessionDTO,
AuthtypesPostableRotateTokenDTO,
@@ -50,12 +49,12 @@ export const createSessionByGoogleCallback = (signal?: AbortSignal) => {
};
export const getCreateSessionByGoogleCallbackQueryKey = () => {
return [`/api/v1/complete/google`] as const;
return ['createSessionByGoogleCallback'] as const;
};
export const getCreateSessionByGoogleCallbackQueryOptions = <
TData = Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
TError = ErrorType<CreateSessionByGoogleCallback303 | RenderErrorResponseDTO>
TError = CreateSessionByGoogleCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
@@ -82,9 +81,9 @@ export const getCreateSessionByGoogleCallbackQueryOptions = <
export type CreateSessionByGoogleCallbackQueryResult = NonNullable<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>
>;
export type CreateSessionByGoogleCallbackQueryError = ErrorType<
CreateSessionByGoogleCallback303 | RenderErrorResponseDTO
>;
export type CreateSessionByGoogleCallbackQueryError =
| CreateSessionByGoogleCallback303
| RenderErrorResponseDTO;
/**
* @summary Create session by google callback
@@ -92,7 +91,7 @@ export type CreateSessionByGoogleCallbackQueryError = ErrorType<
export function useCreateSessionByGoogleCallback<
TData = Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
TError = ErrorType<CreateSessionByGoogleCallback303 | RenderErrorResponseDTO>
TError = CreateSessionByGoogleCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByGoogleCallback>>,
@@ -139,12 +138,12 @@ export const createSessionByOIDCCallback = (signal?: AbortSignal) => {
};
export const getCreateSessionByOIDCCallbackQueryKey = () => {
return [`/api/v1/complete/oidc`] as const;
return ['createSessionByOIDCCallback'] as const;
};
export const getCreateSessionByOIDCCallbackQueryOptions = <
TData = Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
TError = ErrorType<CreateSessionByOIDCCallback303 | RenderErrorResponseDTO>
TError = CreateSessionByOIDCCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
@@ -171,9 +170,9 @@ export const getCreateSessionByOIDCCallbackQueryOptions = <
export type CreateSessionByOIDCCallbackQueryResult = NonNullable<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>
>;
export type CreateSessionByOIDCCallbackQueryError = ErrorType<
CreateSessionByOIDCCallback303 | RenderErrorResponseDTO
>;
export type CreateSessionByOIDCCallbackQueryError =
| CreateSessionByOIDCCallback303
| RenderErrorResponseDTO;
/**
* @summary Create session by oidc callback
@@ -181,7 +180,7 @@ export type CreateSessionByOIDCCallbackQueryError = ErrorType<
export function useCreateSessionByOIDCCallback<
TData = Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
TError = ErrorType<CreateSessionByOIDCCallback303 | RenderErrorResponseDTO>
TError = CreateSessionByOIDCCallback303 | RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof createSessionByOIDCCallback>>,
@@ -220,7 +219,7 @@ export const invalidateCreateSessionByOIDCCallback = async (
* @summary Create session by saml callback
*/
export const createSessionBySAMLCallback = (
createSessionBySAMLCallbackBody: BodyType<CreateSessionBySAMLCallbackBody>,
createSessionBySAMLCallbackBody: CreateSessionBySAMLCallbackBody,
params?: CreateSessionBySAMLCallbackParams,
signal?: AbortSignal,
) => {
@@ -249,14 +248,14 @@ export const createSessionBySAMLCallback = (
};
export const getCreateSessionBySAMLCallbackMutationOptions = <
TError = ErrorType<CreateSessionBySAMLCallback303 | RenderErrorResponseDTO>,
TError = CreateSessionBySAMLCallback303 | RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: BodyType<CreateSessionBySAMLCallbackBody>;
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
@@ -265,7 +264,7 @@ export const getCreateSessionBySAMLCallbackMutationOptions = <
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: BodyType<CreateSessionBySAMLCallbackBody>;
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
@@ -282,7 +281,7 @@ export const getCreateSessionBySAMLCallbackMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
{
data: BodyType<CreateSessionBySAMLCallbackBody>;
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
}
> = (props) => {
@@ -297,23 +296,23 @@ export const getCreateSessionBySAMLCallbackMutationOptions = <
export type CreateSessionBySAMLCallbackMutationResult = NonNullable<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>
>;
export type CreateSessionBySAMLCallbackMutationBody = BodyType<CreateSessionBySAMLCallbackBody>;
export type CreateSessionBySAMLCallbackMutationError = ErrorType<
CreateSessionBySAMLCallback303 | RenderErrorResponseDTO
>;
export type CreateSessionBySAMLCallbackMutationBody = CreateSessionBySAMLCallbackBody;
export type CreateSessionBySAMLCallbackMutationError =
| CreateSessionBySAMLCallback303
| RenderErrorResponseDTO;
/**
* @summary Create session by saml callback
*/
export const useCreateSessionBySAMLCallback = <
TError = ErrorType<CreateSessionBySAMLCallback303 | RenderErrorResponseDTO>,
TError = CreateSessionBySAMLCallback303 | RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: BodyType<CreateSessionBySAMLCallbackBody>;
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
@@ -322,7 +321,7 @@ export const useCreateSessionBySAMLCallback = <
Awaited<ReturnType<typeof createSessionBySAMLCallback>>,
TError,
{
data: BodyType<CreateSessionBySAMLCallbackBody>;
data: CreateSessionBySAMLCallbackBody;
params?: CreateSessionBySAMLCallbackParams;
},
TContext
@@ -343,7 +342,7 @@ export const deleteSession = () => {
};
export const getDeleteSessionMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -381,13 +380,13 @@ export type DeleteSessionMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteSession>>
>;
export type DeleteSessionMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeleteSessionMutationError = RenderErrorResponseDTO;
/**
* @summary Delete session
*/
export const useDeleteSession = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -419,12 +418,12 @@ export const getSessionContext = (signal?: AbortSignal) => {
};
export const getGetSessionContextQueryKey = () => {
return [`/api/v2/sessions/context`] as const;
return ['getSessionContext'] as const;
};
export const getGetSessionContextQueryOptions = <
TData = Awaited<ReturnType<typeof getSessionContext>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getSessionContext>>,
@@ -450,7 +449,7 @@ export const getGetSessionContextQueryOptions = <
export type GetSessionContextQueryResult = NonNullable<
Awaited<ReturnType<typeof getSessionContext>>
>;
export type GetSessionContextQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetSessionContextQueryError = RenderErrorResponseDTO;
/**
* @summary Get session context
@@ -458,7 +457,7 @@ export type GetSessionContextQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetSessionContext<
TData = Awaited<ReturnType<typeof getSessionContext>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof getSessionContext>>,
@@ -497,7 +496,7 @@ export const invalidateGetSessionContext = async (
* @summary Create session by email and password
*/
export const createSessionByEmailPassword = (
authtypesPostableEmailPasswordSessionDTO: BodyType<AuthtypesPostableEmailPasswordSessionDTO>,
authtypesPostableEmailPasswordSessionDTO: AuthtypesPostableEmailPasswordSessionDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateSessionByEmailPassword200>({
@@ -510,19 +509,19 @@ export const createSessionByEmailPassword = (
};
export const getCreateSessionByEmailPasswordMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: BodyType<AuthtypesPostableEmailPasswordSessionDTO> },
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: BodyType<AuthtypesPostableEmailPasswordSessionDTO> },
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
> => {
const mutationKey = ['createSessionByEmailPassword'];
@@ -536,7 +535,7 @@ export const getCreateSessionByEmailPasswordMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
{ data: BodyType<AuthtypesPostableEmailPasswordSessionDTO> }
{ data: AuthtypesPostableEmailPasswordSessionDTO }
> = (props) => {
const { data } = props ?? {};
@@ -549,26 +548,26 @@ export const getCreateSessionByEmailPasswordMutationOptions = <
export type CreateSessionByEmailPasswordMutationResult = NonNullable<
Awaited<ReturnType<typeof createSessionByEmailPassword>>
>;
export type CreateSessionByEmailPasswordMutationBody = BodyType<AuthtypesPostableEmailPasswordSessionDTO>;
export type CreateSessionByEmailPasswordMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateSessionByEmailPasswordMutationBody = AuthtypesPostableEmailPasswordSessionDTO;
export type CreateSessionByEmailPasswordMutationError = RenderErrorResponseDTO;
/**
* @summary Create session by email and password
*/
export const useCreateSessionByEmailPassword = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: BodyType<AuthtypesPostableEmailPasswordSessionDTO> },
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createSessionByEmailPassword>>,
TError,
{ data: BodyType<AuthtypesPostableEmailPasswordSessionDTO> },
{ data: AuthtypesPostableEmailPasswordSessionDTO },
TContext
> => {
const mutationOptions = getCreateSessionByEmailPasswordMutationOptions(
@@ -582,7 +581,7 @@ export const useCreateSessionByEmailPassword = <
* @summary Rotate session
*/
export const rotateSession = (
authtypesPostableRotateTokenDTO: BodyType<AuthtypesPostableRotateTokenDTO>,
authtypesPostableRotateTokenDTO: AuthtypesPostableRotateTokenDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<RotateSession200>({
@@ -595,19 +594,19 @@ export const rotateSession = (
};
export const getRotateSessionMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: BodyType<AuthtypesPostableRotateTokenDTO> },
{ data: AuthtypesPostableRotateTokenDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: BodyType<AuthtypesPostableRotateTokenDTO> },
{ data: AuthtypesPostableRotateTokenDTO },
TContext
> => {
const mutationKey = ['rotateSession'];
@@ -621,7 +620,7 @@ export const getRotateSessionMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof rotateSession>>,
{ data: BodyType<AuthtypesPostableRotateTokenDTO> }
{ data: AuthtypesPostableRotateTokenDTO }
> = (props) => {
const { data } = props ?? {};
@@ -634,26 +633,26 @@ export const getRotateSessionMutationOptions = <
export type RotateSessionMutationResult = NonNullable<
Awaited<ReturnType<typeof rotateSession>>
>;
export type RotateSessionMutationBody = BodyType<AuthtypesPostableRotateTokenDTO>;
export type RotateSessionMutationError = ErrorType<RenderErrorResponseDTO>;
export type RotateSessionMutationBody = AuthtypesPostableRotateTokenDTO;
export type RotateSessionMutationError = RenderErrorResponseDTO;
/**
* @summary Rotate session
*/
export const useRotateSession = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: BodyType<AuthtypesPostableRotateTokenDTO> },
{ data: AuthtypesPostableRotateTokenDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof rotateSession>>,
TError,
{ data: BodyType<AuthtypesPostableRotateTokenDTO> },
{ data: AuthtypesPostableRotateTokenDTO },
TContext
> => {
const mutationOptions = getRotateSessionMutationOptions(options);

View File

@@ -436,7 +436,7 @@ export interface ErrorsJSONDTO {
/**
* @type string
*/
code: string;
code?: string;
/**
* @type array
*/
@@ -444,7 +444,7 @@ export interface ErrorsJSONDTO {
/**
* @type string
*/
message: string;
message?: string;
/**
* @type string
*/
@@ -1985,11 +1985,11 @@ export enum Querybuildertypesv5VariableTypeDTO {
text = 'text',
}
export interface RenderErrorResponseDTO {
error: ErrorsJSONDTO;
error?: ErrorsJSONDTO;
/**
* @type string
*/
status: string;
status?: string;
}
/**
@@ -2599,30 +2599,30 @@ export type AuthzCheck200 = {
/**
* @type array
*/
data: AuthtypesGettableTransactionDTO[];
data?: AuthtypesGettableTransactionDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type ChangePasswordPathParameters = {
id: string;
};
export type CreateSessionByGoogleCallback303 = {
data: AuthtypesGettableTokenDTO;
data?: AuthtypesGettableTokenDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateSessionByOIDCCallback303 = {
data: AuthtypesGettableTokenDTO;
data?: AuthtypesGettableTokenDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateSessionBySAMLCallbackParams = {
@@ -2650,11 +2650,11 @@ export type CreateSessionBySAMLCallbackBody = {
};
export type CreateSessionBySAMLCallback303 = {
data: AuthtypesGettableTokenDTO;
data?: AuthtypesGettableTokenDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type DeletePublicDashboardPathParameters = {
@@ -2664,22 +2664,22 @@ export type GetPublicDashboardPathParameters = {
id: string;
};
export type GetPublicDashboard200 = {
data: DashboardtypesGettablePublicDasbhboardDTO;
data?: DashboardtypesGettablePublicDasbhboardDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type CreatePublicDashboardPathParameters = {
id: string;
};
export type CreatePublicDashboard201 = {
data: TypesIdentifiableDTO;
data?: TypesIdentifiableDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type UpdatePublicDashboardPathParameters = {
@@ -2689,19 +2689,19 @@ export type ListAuthDomains200 = {
/**
* @type array
*/
data: AuthtypesGettableAuthDomainDTO[];
data?: AuthtypesGettableAuthDomainDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateAuthDomain200 = {
data: AuthtypesGettableAuthDomainDTO;
data?: AuthtypesGettableAuthDomainDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type DeleteAuthDomainPathParameters = {
@@ -2757,11 +2757,11 @@ export type GetFieldsKeysParams = {
};
export type GetFieldsKeys200 = {
data: TelemetrytypesGettableFieldKeysDTO;
data?: TelemetrytypesGettableFieldKeysDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetFieldsValuesParams = {
@@ -2821,49 +2821,49 @@ export type GetFieldsValuesParams = {
};
export type GetFieldsValues200 = {
data: TelemetrytypesGettableFieldValuesDTO;
data?: TelemetrytypesGettableFieldValuesDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetResetPasswordTokenPathParameters = {
id: string;
};
export type GetResetPasswordToken200 = {
data: TypesResetPasswordTokenDTO;
data?: TypesResetPasswordTokenDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetGlobalConfig200 = {
data: TypesGettableGlobalConfigDTO;
data?: TypesGettableGlobalConfigDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type ListInvite200 = {
/**
* @type array
*/
data: TypesInviteDTO[];
data?: TypesInviteDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateInvite201 = {
data: TypesInviteDTO;
data?: TypesInviteDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type DeleteInvitePathParameters = {
@@ -2873,19 +2873,19 @@ export type GetInvitePathParameters = {
token: string;
};
export type GetInvite200 = {
data: TypesInviteDTO;
data?: TypesInviteDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type AcceptInvite201 = {
data: TypesUserDTO;
data?: TypesUserDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type ListPromotedAndIndexedPaths200 = {
@@ -2893,33 +2893,33 @@ export type ListPromotedAndIndexedPaths200 = {
* @type array
* @nullable true
*/
data: PromotetypesPromotePathDTO[] | null;
data?: PromotetypesPromotePathDTO[] | null;
/**
* @type string
*/
status: string;
status?: string;
};
export type ListOrgPreferences200 = {
/**
* @type array
*/
data: PreferencetypesPreferenceDTO[];
data?: PreferencetypesPreferenceDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type GetOrgPreferencePathParameters = {
name: string;
};
export type GetOrgPreference200 = {
data: PreferencetypesPreferenceDTO;
data?: PreferencetypesPreferenceDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type UpdateOrgPreferencePathParameters = {
@@ -2929,19 +2929,19 @@ export type ListAPIKeys200 = {
/**
* @type array
*/
data: TypesGettableAPIKeyDTO[];
data?: TypesGettableAPIKeyDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateAPIKey201 = {
data: TypesGettableAPIKeyDTO;
data?: TypesGettableAPIKeyDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type RevokeAPIKeyPathParameters = {
@@ -2954,11 +2954,11 @@ export type GetPublicDashboardDataPathParameters = {
id: string;
};
export type GetPublicDashboardData200 = {
data: DashboardtypesGettablePublicDashboardDataDTO;
data?: DashboardtypesGettablePublicDashboardDataDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetPublicDashboardWidgetQueryRangePathParameters = {
@@ -2966,30 +2966,30 @@ export type GetPublicDashboardWidgetQueryRangePathParameters = {
idx: string;
};
export type GetPublicDashboardWidgetQueryRange200 = {
data: Querybuildertypesv5QueryRangeResponseDTO;
data?: Querybuildertypesv5QueryRangeResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type ListRoles200 = {
/**
* @type array
*/
data: RoletypesRoleDTO[];
data?: RoletypesRoleDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateRole201 = {
data: TypesIdentifiableDTO;
data?: TypesIdentifiableDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type DeleteRolePathParameters = {
@@ -2999,11 +2999,11 @@ export type GetRolePathParameters = {
id: string;
};
export type GetRole200 = {
data: RoletypesRoleDTO;
data?: RoletypesRoleDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type PatchRolePathParameters = {
@@ -3017,11 +3017,11 @@ export type GetObjects200 = {
/**
* @type array
*/
data: AuthtypesObjectDTO[];
data?: AuthtypesObjectDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type PatchObjectsPathParameters = {
@@ -3029,22 +3029,22 @@ export type PatchObjectsPathParameters = {
relation: string;
};
export type GetResources200 = {
data: RoletypesGettableResourcesDTO;
data?: RoletypesGettableResourcesDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type ListUsers200 = {
/**
* @type array
*/
data: TypesUserDTO[];
data?: TypesUserDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type DeleteUserPathParameters = {
@@ -3054,52 +3054,52 @@ export type GetUserPathParameters = {
id: string;
};
export type GetUser200 = {
data: TypesUserDTO;
data?: TypesUserDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type UpdateUserPathParameters = {
id: string;
};
export type UpdateUser200 = {
data: TypesUserDTO;
data?: TypesUserDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMyUser200 = {
data: TypesUserDTO;
data?: TypesUserDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type ListUserPreferences200 = {
/**
* @type array
*/
data: PreferencetypesPreferenceDTO[];
data?: PreferencetypesPreferenceDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type GetUserPreferencePathParameters = {
name: string;
};
export type GetUserPreference200 = {
data: PreferencetypesPreferenceDTO;
data?: PreferencetypesPreferenceDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type UpdateUserPreferencePathParameters = {
@@ -3109,11 +3109,11 @@ export type GetFeatures200 = {
/**
* @type array
*/
data: FeaturetypesGettableFeatureDTO[];
data?: FeaturetypesGettableFeatureDTO[];
/**
* @type string
*/
status: string;
status?: string;
};
export type GetIngestionKeysParams = {
@@ -3130,19 +3130,19 @@ export type GetIngestionKeysParams = {
};
export type GetIngestionKeys200 = {
data: GatewaytypesGettableIngestionKeysDTO;
data?: GatewaytypesGettableIngestionKeysDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateIngestionKey200 = {
data: GatewaytypesGettableCreatedIngestionKeyDTO;
data?: GatewaytypesGettableCreatedIngestionKeyDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type DeleteIngestionKeyPathParameters = {
@@ -3155,11 +3155,11 @@ export type CreateIngestionKeyLimitPathParameters = {
keyId: string;
};
export type CreateIngestionKeyLimit201 = {
data: GatewaytypesGettableCreatedIngestionKeyLimitDTO;
data?: GatewaytypesGettableCreatedIngestionKeyLimitDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type DeleteIngestionKeyLimitPathParameters = {
@@ -3187,11 +3187,11 @@ export type SearchIngestionKeysParams = {
};
export type SearchIngestionKeys200 = {
data: GatewaytypesGettableIngestionKeysDTO;
data?: GatewaytypesGettableIngestionKeysDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type ListMetricsParams = {
@@ -3220,22 +3220,22 @@ export type ListMetricsParams = {
};
export type ListMetrics200 = {
data: MetricsexplorertypesListMetricsResponseDTO;
data?: MetricsexplorertypesListMetricsResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMetricAlertsPathParameters = {
metricName: string;
};
export type GetMetricAlerts200 = {
data: MetricsexplorertypesMetricAlertsResponseDTO;
data?: MetricsexplorertypesMetricAlertsResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMetricAttributesPathParameters = {
@@ -3257,117 +3257,117 @@ export type GetMetricAttributesParams = {
};
export type GetMetricAttributes200 = {
data: MetricsexplorertypesMetricAttributesResponseDTO;
data?: MetricsexplorertypesMetricAttributesResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMetricDashboardsPathParameters = {
metricName: string;
};
export type GetMetricDashboards200 = {
data: MetricsexplorertypesMetricDashboardsResponseDTO;
data?: MetricsexplorertypesMetricDashboardsResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMetricHighlightsPathParameters = {
metricName: string;
};
export type GetMetricHighlights200 = {
data: MetricsexplorertypesMetricHighlightsResponseDTO;
data?: MetricsexplorertypesMetricHighlightsResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMetricMetadataPathParameters = {
metricName: string;
};
export type GetMetricMetadata200 = {
data: MetricsexplorertypesMetricMetadataDTO;
data?: MetricsexplorertypesMetricMetadataDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type UpdateMetricMetadataPathParameters = {
metricName: string;
};
export type GetMetricsStats200 = {
data: MetricsexplorertypesStatsResponseDTO;
data?: MetricsexplorertypesStatsResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMetricsTreemap200 = {
data: MetricsexplorertypesTreemapResponseDTO;
data?: MetricsexplorertypesTreemapResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetMyOrganization200 = {
data: TypesOrganizationDTO;
data?: TypesOrganizationDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetSessionContext200 = {
data: AuthtypesSessionContextDTO;
data?: AuthtypesSessionContextDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type CreateSessionByEmailPassword200 = {
data: AuthtypesGettableTokenDTO;
data?: AuthtypesGettableTokenDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type RotateSession200 = {
data: AuthtypesGettableTokenDTO;
data?: AuthtypesGettableTokenDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type GetHosts200 = {
data: ZeustypesGettableHostDTO;
data?: ZeustypesGettableHostDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type QueryRangeV5200 = {
data: Querybuildertypesv5QueryRangeResponseDTO;
data?: Querybuildertypesv5QueryRangeResponseDTO;
/**
* @type string
*/
status: string;
status?: string;
};
export type ReplaceVariables200 = {
data: Querybuildertypesv5QueryRangeRequestDTO;
data?: Querybuildertypesv5QueryRangeRequestDTO;
/**
* @type string
*/
status: string;
status?: string;
};

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
AcceptInvite201,
ChangePasswordPathParameters,
@@ -61,7 +60,7 @@ type Awaited<O> = O extends AwaitedInput<infer T> ? T : never;
*/
export const changePassword = (
{ id }: ChangePasswordPathParameters,
typesChangePasswordRequestDTO: BodyType<TypesChangePasswordRequestDTO>,
typesChangePasswordRequestDTO: TypesChangePasswordRequestDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
@@ -74,7 +73,7 @@ export const changePassword = (
};
export const getChangePasswordMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -82,7 +81,7 @@ export const getChangePasswordMutationOptions = <
TError,
{
pathParams: ChangePasswordPathParameters;
data: BodyType<TypesChangePasswordRequestDTO>;
data: TypesChangePasswordRequestDTO;
},
TContext
>;
@@ -91,7 +90,7 @@ export const getChangePasswordMutationOptions = <
TError,
{
pathParams: ChangePasswordPathParameters;
data: BodyType<TypesChangePasswordRequestDTO>;
data: TypesChangePasswordRequestDTO;
},
TContext
> => {
@@ -108,7 +107,7 @@ export const getChangePasswordMutationOptions = <
Awaited<ReturnType<typeof changePassword>>,
{
pathParams: ChangePasswordPathParameters;
data: BodyType<TypesChangePasswordRequestDTO>;
data: TypesChangePasswordRequestDTO;
}
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -122,14 +121,14 @@ export const getChangePasswordMutationOptions = <
export type ChangePasswordMutationResult = NonNullable<
Awaited<ReturnType<typeof changePassword>>
>;
export type ChangePasswordMutationBody = BodyType<TypesChangePasswordRequestDTO>;
export type ChangePasswordMutationError = ErrorType<RenderErrorResponseDTO>;
export type ChangePasswordMutationBody = TypesChangePasswordRequestDTO;
export type ChangePasswordMutationError = RenderErrorResponseDTO;
/**
* @summary Change password
*/
export const useChangePassword = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -137,7 +136,7 @@ export const useChangePassword = <
TError,
{
pathParams: ChangePasswordPathParameters;
data: BodyType<TypesChangePasswordRequestDTO>;
data: TypesChangePasswordRequestDTO;
},
TContext
>;
@@ -146,7 +145,7 @@ export const useChangePassword = <
TError,
{
pathParams: ChangePasswordPathParameters;
data: BodyType<TypesChangePasswordRequestDTO>;
data: TypesChangePasswordRequestDTO;
},
TContext
> => {
@@ -172,12 +171,12 @@ export const getResetPasswordToken = (
export const getGetResetPasswordTokenQueryKey = ({
id,
}: GetResetPasswordTokenPathParameters) => {
return [`/api/v1/getResetPasswordToken/${id}`] as const;
return ['getResetPasswordToken'] as const;
};
export const getGetResetPasswordTokenQueryOptions = <
TData = Awaited<ReturnType<typeof getResetPasswordToken>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetResetPasswordTokenPathParameters,
options?: {
@@ -212,7 +211,7 @@ export const getGetResetPasswordTokenQueryOptions = <
export type GetResetPasswordTokenQueryResult = NonNullable<
Awaited<ReturnType<typeof getResetPasswordToken>>
>;
export type GetResetPasswordTokenQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetResetPasswordTokenQueryError = RenderErrorResponseDTO;
/**
* @summary Get reset password token
@@ -220,7 +219,7 @@ export type GetResetPasswordTokenQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetResetPasswordToken<
TData = Awaited<ReturnType<typeof getResetPasswordToken>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetResetPasswordTokenPathParameters,
options?: {
@@ -271,12 +270,12 @@ export const listInvite = (signal?: AbortSignal) => {
};
export const getListInviteQueryKey = () => {
return [`/api/v1/invite`] as const;
return ['listInvite'] as const;
};
export const getListInviteQueryOptions = <
TData = Awaited<ReturnType<typeof listInvite>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listInvite>>, TError, TData>;
}) => {
@@ -298,7 +297,7 @@ export const getListInviteQueryOptions = <
export type ListInviteQueryResult = NonNullable<
Awaited<ReturnType<typeof listInvite>>
>;
export type ListInviteQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListInviteQueryError = RenderErrorResponseDTO;
/**
* @summary List invites
@@ -306,7 +305,7 @@ export type ListInviteQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListInvite<
TData = Awaited<ReturnType<typeof listInvite>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listInvite>>, TError, TData>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
@@ -341,7 +340,7 @@ export const invalidateListInvite = async (
* @summary Create invite
*/
export const createInvite = (
typesPostableInviteDTO: BodyType<TypesPostableInviteDTO>,
typesPostableInviteDTO: TypesPostableInviteDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateInvite201>({
@@ -354,19 +353,19 @@ export const createInvite = (
};
export const getCreateInviteMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO> },
{ data: TypesPostableInviteDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO> },
{ data: TypesPostableInviteDTO },
TContext
> => {
const mutationKey = ['createInvite'];
@@ -380,7 +379,7 @@ export const getCreateInviteMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createInvite>>,
{ data: BodyType<TypesPostableInviteDTO> }
{ data: TypesPostableInviteDTO }
> = (props) => {
const { data } = props ?? {};
@@ -393,26 +392,26 @@ export const getCreateInviteMutationOptions = <
export type CreateInviteMutationResult = NonNullable<
Awaited<ReturnType<typeof createInvite>>
>;
export type CreateInviteMutationBody = BodyType<TypesPostableInviteDTO>;
export type CreateInviteMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateInviteMutationBody = TypesPostableInviteDTO;
export type CreateInviteMutationError = RenderErrorResponseDTO;
/**
* @summary Create invite
*/
export const useCreateInvite = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO> },
{ data: TypesPostableInviteDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO> },
{ data: TypesPostableInviteDTO },
TContext
> => {
const mutationOptions = getCreateInviteMutationOptions(options);
@@ -431,7 +430,7 @@ export const deleteInvite = ({ id }: DeleteInvitePathParameters) => {
};
export const getDeleteInviteMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -471,13 +470,13 @@ export type DeleteInviteMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteInvite>>
>;
export type DeleteInviteMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeleteInviteMutationError = RenderErrorResponseDTO;
/**
* @summary Delete invite
*/
export const useDeleteInvite = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -512,12 +511,12 @@ export const getInvite = (
};
export const getGetInviteQueryKey = ({ token }: GetInvitePathParameters) => {
return [`/api/v1/invite/${token}`] as const;
return ['getInvite'] as const;
};
export const getGetInviteQueryOptions = <
TData = Awaited<ReturnType<typeof getInvite>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ token }: GetInvitePathParameters,
options?: {
@@ -545,7 +544,7 @@ export const getGetInviteQueryOptions = <
export type GetInviteQueryResult = NonNullable<
Awaited<ReturnType<typeof getInvite>>
>;
export type GetInviteQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetInviteQueryError = RenderErrorResponseDTO;
/**
* @summary Get invite
@@ -553,7 +552,7 @@ export type GetInviteQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetInvite<
TData = Awaited<ReturnType<typeof getInvite>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ token }: GetInvitePathParameters,
options?: {
@@ -592,7 +591,7 @@ export const invalidateGetInvite = async (
* @summary Accept invite
*/
export const acceptInvite = (
typesPostableAcceptInviteDTO: BodyType<TypesPostableAcceptInviteDTO>,
typesPostableAcceptInviteDTO: TypesPostableAcceptInviteDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<AcceptInvite201>({
@@ -605,19 +604,19 @@ export const acceptInvite = (
};
export const getAcceptInviteMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof acceptInvite>>,
TError,
{ data: BodyType<TypesPostableAcceptInviteDTO> },
{ data: TypesPostableAcceptInviteDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof acceptInvite>>,
TError,
{ data: BodyType<TypesPostableAcceptInviteDTO> },
{ data: TypesPostableAcceptInviteDTO },
TContext
> => {
const mutationKey = ['acceptInvite'];
@@ -631,7 +630,7 @@ export const getAcceptInviteMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof acceptInvite>>,
{ data: BodyType<TypesPostableAcceptInviteDTO> }
{ data: TypesPostableAcceptInviteDTO }
> = (props) => {
const { data } = props ?? {};
@@ -644,26 +643,26 @@ export const getAcceptInviteMutationOptions = <
export type AcceptInviteMutationResult = NonNullable<
Awaited<ReturnType<typeof acceptInvite>>
>;
export type AcceptInviteMutationBody = BodyType<TypesPostableAcceptInviteDTO>;
export type AcceptInviteMutationError = ErrorType<RenderErrorResponseDTO>;
export type AcceptInviteMutationBody = TypesPostableAcceptInviteDTO;
export type AcceptInviteMutationError = RenderErrorResponseDTO;
/**
* @summary Accept invite
*/
export const useAcceptInvite = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof acceptInvite>>,
TError,
{ data: BodyType<TypesPostableAcceptInviteDTO> },
{ data: TypesPostableAcceptInviteDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof acceptInvite>>,
TError,
{ data: BodyType<TypesPostableAcceptInviteDTO> },
{ data: TypesPostableAcceptInviteDTO },
TContext
> => {
const mutationOptions = getAcceptInviteMutationOptions(options);
@@ -675,7 +674,7 @@ export const useAcceptInvite = <
* @summary Create bulk invite
*/
export const createBulkInvite = (
typesPostableInviteDTO: BodyType<TypesPostableInviteDTO[]>,
typesPostableInviteDTO: TypesPostableInviteDTO[],
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
@@ -688,19 +687,19 @@ export const createBulkInvite = (
};
export const getCreateBulkInviteMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createBulkInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO[]> },
{ data: TypesPostableInviteDTO[] },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createBulkInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO[]> },
{ data: TypesPostableInviteDTO[] },
TContext
> => {
const mutationKey = ['createBulkInvite'];
@@ -714,7 +713,7 @@ export const getCreateBulkInviteMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createBulkInvite>>,
{ data: BodyType<TypesPostableInviteDTO[]> }
{ data: TypesPostableInviteDTO[] }
> = (props) => {
const { data } = props ?? {};
@@ -727,26 +726,26 @@ export const getCreateBulkInviteMutationOptions = <
export type CreateBulkInviteMutationResult = NonNullable<
Awaited<ReturnType<typeof createBulkInvite>>
>;
export type CreateBulkInviteMutationBody = BodyType<TypesPostableInviteDTO[]>;
export type CreateBulkInviteMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateBulkInviteMutationBody = TypesPostableInviteDTO[];
export type CreateBulkInviteMutationError = RenderErrorResponseDTO;
/**
* @summary Create bulk invite
*/
export const useCreateBulkInvite = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createBulkInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO[]> },
{ data: TypesPostableInviteDTO[] },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createBulkInvite>>,
TError,
{ data: BodyType<TypesPostableInviteDTO[]> },
{ data: TypesPostableInviteDTO[] },
TContext
> => {
const mutationOptions = getCreateBulkInviteMutationOptions(options);
@@ -766,12 +765,12 @@ export const listAPIKeys = (signal?: AbortSignal) => {
};
export const getListAPIKeysQueryKey = () => {
return [`/api/v1/pats`] as const;
return ['listAPIKeys'] as const;
};
export const getListAPIKeysQueryOptions = <
TData = Awaited<ReturnType<typeof listAPIKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listAPIKeys>>,
@@ -797,7 +796,7 @@ export const getListAPIKeysQueryOptions = <
export type ListAPIKeysQueryResult = NonNullable<
Awaited<ReturnType<typeof listAPIKeys>>
>;
export type ListAPIKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListAPIKeysQueryError = RenderErrorResponseDTO;
/**
* @summary List api keys
@@ -805,7 +804,7 @@ export type ListAPIKeysQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListAPIKeys<
TData = Awaited<ReturnType<typeof listAPIKeys>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<
Awaited<ReturnType<typeof listAPIKeys>>,
@@ -844,7 +843,7 @@ export const invalidateListAPIKeys = async (
* @summary Create api key
*/
export const createAPIKey = (
typesPostableAPIKeyDTO: BodyType<TypesPostableAPIKeyDTO>,
typesPostableAPIKeyDTO: TypesPostableAPIKeyDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<CreateAPIKey201>({
@@ -857,19 +856,19 @@ export const createAPIKey = (
};
export const getCreateAPIKeyMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createAPIKey>>,
TError,
{ data: BodyType<TypesPostableAPIKeyDTO> },
{ data: TypesPostableAPIKeyDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof createAPIKey>>,
TError,
{ data: BodyType<TypesPostableAPIKeyDTO> },
{ data: TypesPostableAPIKeyDTO },
TContext
> => {
const mutationKey = ['createAPIKey'];
@@ -883,7 +882,7 @@ export const getCreateAPIKeyMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof createAPIKey>>,
{ data: BodyType<TypesPostableAPIKeyDTO> }
{ data: TypesPostableAPIKeyDTO }
> = (props) => {
const { data } = props ?? {};
@@ -896,26 +895,26 @@ export const getCreateAPIKeyMutationOptions = <
export type CreateAPIKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof createAPIKey>>
>;
export type CreateAPIKeyMutationBody = BodyType<TypesPostableAPIKeyDTO>;
export type CreateAPIKeyMutationError = ErrorType<RenderErrorResponseDTO>;
export type CreateAPIKeyMutationBody = TypesPostableAPIKeyDTO;
export type CreateAPIKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Create api key
*/
export const useCreateAPIKey = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof createAPIKey>>,
TError,
{ data: BodyType<TypesPostableAPIKeyDTO> },
{ data: TypesPostableAPIKeyDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof createAPIKey>>,
TError,
{ data: BodyType<TypesPostableAPIKeyDTO> },
{ data: TypesPostableAPIKeyDTO },
TContext
> => {
const mutationOptions = getCreateAPIKeyMutationOptions(options);
@@ -934,7 +933,7 @@ export const revokeAPIKey = ({ id }: RevokeAPIKeyPathParameters) => {
};
export const getRevokeAPIKeyMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -974,13 +973,13 @@ export type RevokeAPIKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof revokeAPIKey>>
>;
export type RevokeAPIKeyMutationError = ErrorType<RenderErrorResponseDTO>;
export type RevokeAPIKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Revoke api key
*/
export const useRevokeAPIKey = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -1005,7 +1004,7 @@ export const useRevokeAPIKey = <
*/
export const updateAPIKey = (
{ id }: UpdateAPIKeyPathParameters,
typesStorableAPIKeyDTO: BodyType<TypesStorableAPIKeyDTO>,
typesStorableAPIKeyDTO: TypesStorableAPIKeyDTO,
) => {
return GeneratedAPIInstance<string>({
url: `/api/v1/pats/${id}`,
@@ -1016,25 +1015,19 @@ export const updateAPIKey = (
};
export const getUpdateAPIKeyMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateAPIKey>>,
TError,
{
pathParams: UpdateAPIKeyPathParameters;
data: BodyType<TypesStorableAPIKeyDTO>;
},
{ pathParams: UpdateAPIKeyPathParameters; data: TypesStorableAPIKeyDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateAPIKey>>,
TError,
{
pathParams: UpdateAPIKeyPathParameters;
data: BodyType<TypesStorableAPIKeyDTO>;
},
{ pathParams: UpdateAPIKeyPathParameters; data: TypesStorableAPIKeyDTO },
TContext
> => {
const mutationKey = ['updateAPIKey'];
@@ -1048,10 +1041,7 @@ export const getUpdateAPIKeyMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateAPIKey>>,
{
pathParams: UpdateAPIKeyPathParameters;
data: BodyType<TypesStorableAPIKeyDTO>;
}
{ pathParams: UpdateAPIKeyPathParameters; data: TypesStorableAPIKeyDTO }
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -1064,32 +1054,26 @@ export const getUpdateAPIKeyMutationOptions = <
export type UpdateAPIKeyMutationResult = NonNullable<
Awaited<ReturnType<typeof updateAPIKey>>
>;
export type UpdateAPIKeyMutationBody = BodyType<TypesStorableAPIKeyDTO>;
export type UpdateAPIKeyMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateAPIKeyMutationBody = TypesStorableAPIKeyDTO;
export type UpdateAPIKeyMutationError = RenderErrorResponseDTO;
/**
* @summary Update api key
*/
export const useUpdateAPIKey = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateAPIKey>>,
TError,
{
pathParams: UpdateAPIKeyPathParameters;
data: BodyType<TypesStorableAPIKeyDTO>;
},
{ pathParams: UpdateAPIKeyPathParameters; data: TypesStorableAPIKeyDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateAPIKey>>,
TError,
{
pathParams: UpdateAPIKeyPathParameters;
data: BodyType<TypesStorableAPIKeyDTO>;
},
{ pathParams: UpdateAPIKeyPathParameters; data: TypesStorableAPIKeyDTO },
TContext
> => {
const mutationOptions = getUpdateAPIKeyMutationOptions(options);
@@ -1101,7 +1085,7 @@ export const useUpdateAPIKey = <
* @summary Reset password
*/
export const resetPassword = (
typesPostableResetPasswordDTO: BodyType<TypesPostableResetPasswordDTO>,
typesPostableResetPasswordDTO: TypesPostableResetPasswordDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
@@ -1114,19 +1098,19 @@ export const resetPassword = (
};
export const getResetPasswordMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof resetPassword>>,
TError,
{ data: BodyType<TypesPostableResetPasswordDTO> },
{ data: TypesPostableResetPasswordDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof resetPassword>>,
TError,
{ data: BodyType<TypesPostableResetPasswordDTO> },
{ data: TypesPostableResetPasswordDTO },
TContext
> => {
const mutationKey = ['resetPassword'];
@@ -1140,7 +1124,7 @@ export const getResetPasswordMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof resetPassword>>,
{ data: BodyType<TypesPostableResetPasswordDTO> }
{ data: TypesPostableResetPasswordDTO }
> = (props) => {
const { data } = props ?? {};
@@ -1153,26 +1137,26 @@ export const getResetPasswordMutationOptions = <
export type ResetPasswordMutationResult = NonNullable<
Awaited<ReturnType<typeof resetPassword>>
>;
export type ResetPasswordMutationBody = BodyType<TypesPostableResetPasswordDTO>;
export type ResetPasswordMutationError = ErrorType<RenderErrorResponseDTO>;
export type ResetPasswordMutationBody = TypesPostableResetPasswordDTO;
export type ResetPasswordMutationError = RenderErrorResponseDTO;
/**
* @summary Reset password
*/
export const useResetPassword = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof resetPassword>>,
TError,
{ data: BodyType<TypesPostableResetPasswordDTO> },
{ data: TypesPostableResetPasswordDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof resetPassword>>,
TError,
{ data: BodyType<TypesPostableResetPasswordDTO> },
{ data: TypesPostableResetPasswordDTO },
TContext
> => {
const mutationOptions = getResetPasswordMutationOptions(options);
@@ -1192,12 +1176,12 @@ export const listUsers = (signal?: AbortSignal) => {
};
export const getListUsersQueryKey = () => {
return [`/api/v1/user`] as const;
return ['listUsers'] as const;
};
export const getListUsersQueryOptions = <
TData = Awaited<ReturnType<typeof listUsers>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listUsers>>, TError, TData>;
}) => {
@@ -1219,7 +1203,7 @@ export const getListUsersQueryOptions = <
export type ListUsersQueryResult = NonNullable<
Awaited<ReturnType<typeof listUsers>>
>;
export type ListUsersQueryError = ErrorType<RenderErrorResponseDTO>;
export type ListUsersQueryError = RenderErrorResponseDTO;
/**
* @summary List users
@@ -1227,7 +1211,7 @@ export type ListUsersQueryError = ErrorType<RenderErrorResponseDTO>;
export function useListUsers<
TData = Awaited<ReturnType<typeof listUsers>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof listUsers>>, TError, TData>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
@@ -1269,7 +1253,7 @@ export const deleteUser = ({ id }: DeleteUserPathParameters) => {
};
export const getDeleteUserMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -1309,13 +1293,13 @@ export type DeleteUserMutationResult = NonNullable<
Awaited<ReturnType<typeof deleteUser>>
>;
export type DeleteUserMutationError = ErrorType<RenderErrorResponseDTO>;
export type DeleteUserMutationError = RenderErrorResponseDTO;
/**
* @summary Delete user
*/
export const useDeleteUser = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
@@ -1350,12 +1334,12 @@ export const getUser = (
};
export const getGetUserQueryKey = ({ id }: GetUserPathParameters) => {
return [`/api/v1/user/${id}`] as const;
return ['getUser'] as const;
};
export const getGetUserQueryOptions = <
TData = Awaited<ReturnType<typeof getUser>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetUserPathParameters,
options?: {
@@ -1383,7 +1367,7 @@ export const getGetUserQueryOptions = <
export type GetUserQueryResult = NonNullable<
Awaited<ReturnType<typeof getUser>>
>;
export type GetUserQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetUserQueryError = RenderErrorResponseDTO;
/**
* @summary Get user
@@ -1391,7 +1375,7 @@ export type GetUserQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetUser<
TData = Awaited<ReturnType<typeof getUser>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(
{ id }: GetUserPathParameters,
options?: {
@@ -1431,7 +1415,7 @@ export const invalidateGetUser = async (
*/
export const updateUser = (
{ id }: UpdateUserPathParameters,
typesUserDTO: BodyType<TypesUserDTO>,
typesUserDTO: TypesUserDTO,
) => {
return GeneratedAPIInstance<UpdateUser200>({
url: `/api/v1/user/${id}`,
@@ -1442,19 +1426,19 @@ export const updateUser = (
};
export const getUpdateUserMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateUser>>,
TError,
{ pathParams: UpdateUserPathParameters; data: BodyType<TypesUserDTO> },
{ pathParams: UpdateUserPathParameters; data: TypesUserDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof updateUser>>,
TError,
{ pathParams: UpdateUserPathParameters; data: BodyType<TypesUserDTO> },
{ pathParams: UpdateUserPathParameters; data: TypesUserDTO },
TContext
> => {
const mutationKey = ['updateUser'];
@@ -1468,7 +1452,7 @@ export const getUpdateUserMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof updateUser>>,
{ pathParams: UpdateUserPathParameters; data: BodyType<TypesUserDTO> }
{ pathParams: UpdateUserPathParameters; data: TypesUserDTO }
> = (props) => {
const { pathParams, data } = props ?? {};
@@ -1481,26 +1465,26 @@ export const getUpdateUserMutationOptions = <
export type UpdateUserMutationResult = NonNullable<
Awaited<ReturnType<typeof updateUser>>
>;
export type UpdateUserMutationBody = BodyType<TypesUserDTO>;
export type UpdateUserMutationError = ErrorType<RenderErrorResponseDTO>;
export type UpdateUserMutationBody = TypesUserDTO;
export type UpdateUserMutationError = RenderErrorResponseDTO;
/**
* @summary Update user
*/
export const useUpdateUser = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof updateUser>>,
TError,
{ pathParams: UpdateUserPathParameters; data: BodyType<TypesUserDTO> },
{ pathParams: UpdateUserPathParameters; data: TypesUserDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof updateUser>>,
TError,
{ pathParams: UpdateUserPathParameters; data: BodyType<TypesUserDTO> },
{ pathParams: UpdateUserPathParameters; data: TypesUserDTO },
TContext
> => {
const mutationOptions = getUpdateUserMutationOptions(options);
@@ -1520,12 +1504,12 @@ export const getMyUser = (signal?: AbortSignal) => {
};
export const getGetMyUserQueryKey = () => {
return [`/api/v1/user/me`] as const;
return ['getMyUser'] as const;
};
export const getGetMyUserQueryOptions = <
TData = Awaited<ReturnType<typeof getMyUser>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getMyUser>>, TError, TData>;
}) => {
@@ -1547,7 +1531,7 @@ export const getGetMyUserQueryOptions = <
export type GetMyUserQueryResult = NonNullable<
Awaited<ReturnType<typeof getMyUser>>
>;
export type GetMyUserQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetMyUserQueryError = RenderErrorResponseDTO;
/**
* @summary Get my user
@@ -1555,7 +1539,7 @@ export type GetMyUserQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetMyUser<
TData = Awaited<ReturnType<typeof getMyUser>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getMyUser>>, TError, TData>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
@@ -1590,7 +1574,7 @@ export const invalidateGetMyUser = async (
* @summary Forgot password
*/
export const forgotPassword = (
typesPostableForgotPasswordDTO: BodyType<TypesPostableForgotPasswordDTO>,
typesPostableForgotPasswordDTO: TypesPostableForgotPasswordDTO,
signal?: AbortSignal,
) => {
return GeneratedAPIInstance<void>({
@@ -1603,19 +1587,19 @@ export const forgotPassword = (
};
export const getForgotPasswordMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: BodyType<TypesPostableForgotPasswordDTO> },
{ data: TypesPostableForgotPasswordDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: BodyType<TypesPostableForgotPasswordDTO> },
{ data: TypesPostableForgotPasswordDTO },
TContext
> => {
const mutationKey = ['forgotPassword'];
@@ -1629,7 +1613,7 @@ export const getForgotPasswordMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof forgotPassword>>,
{ data: BodyType<TypesPostableForgotPasswordDTO> }
{ data: TypesPostableForgotPasswordDTO }
> = (props) => {
const { data } = props ?? {};
@@ -1642,26 +1626,26 @@ export const getForgotPasswordMutationOptions = <
export type ForgotPasswordMutationResult = NonNullable<
Awaited<ReturnType<typeof forgotPassword>>
>;
export type ForgotPasswordMutationBody = BodyType<TypesPostableForgotPasswordDTO>;
export type ForgotPasswordMutationError = ErrorType<RenderErrorResponseDTO>;
export type ForgotPasswordMutationBody = TypesPostableForgotPasswordDTO;
export type ForgotPasswordMutationError = RenderErrorResponseDTO;
/**
* @summary Forgot password
*/
export const useForgotPassword = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: BodyType<TypesPostableForgotPasswordDTO> },
{ data: TypesPostableForgotPasswordDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof forgotPassword>>,
TError,
{ data: BodyType<TypesPostableForgotPasswordDTO> },
{ data: TypesPostableForgotPasswordDTO },
TContext
> => {
const mutationOptions = getForgotPasswordMutationOptions(options);

View File

@@ -17,8 +17,7 @@ import type {
} from 'react-query';
import { useMutation, useQuery } from 'react-query';
import type { BodyType, ErrorType } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../generatedAPIInstance';
import { GeneratedAPIInstance } from '../../../index';
import type {
GetHosts200,
RenderErrorResponseDTO,
@@ -43,12 +42,12 @@ export const getHosts = (signal?: AbortSignal) => {
};
export const getGetHostsQueryKey = () => {
return [`/api/v2/zeus/hosts`] as const;
return ['getHosts'] as const;
};
export const getGetHostsQueryOptions = <
TData = Awaited<ReturnType<typeof getHosts>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getHosts>>, TError, TData>;
}) => {
@@ -70,7 +69,7 @@ export const getGetHostsQueryOptions = <
export type GetHostsQueryResult = NonNullable<
Awaited<ReturnType<typeof getHosts>>
>;
export type GetHostsQueryError = ErrorType<RenderErrorResponseDTO>;
export type GetHostsQueryError = RenderErrorResponseDTO;
/**
* @summary Get host info from Zeus.
@@ -78,7 +77,7 @@ export type GetHostsQueryError = ErrorType<RenderErrorResponseDTO>;
export function useGetHosts<
TData = Awaited<ReturnType<typeof getHosts>>,
TError = ErrorType<RenderErrorResponseDTO>
TError = RenderErrorResponseDTO
>(options?: {
query?: UseQueryOptions<Awaited<ReturnType<typeof getHosts>>, TError, TData>;
}): UseQueryResult<TData, TError> & { queryKey: QueryKey } {
@@ -112,9 +111,7 @@ export const invalidateGetHosts = async (
* This endpoint saves the host of a deployment to zeus.
* @summary Put host in Zeus for a deployment.
*/
export const putHost = (
zeustypesPostableHostDTO: BodyType<ZeustypesPostableHostDTO>,
) => {
export const putHost = (zeustypesPostableHostDTO: ZeustypesPostableHostDTO) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/zeus/hosts`,
method: 'PUT',
@@ -124,19 +121,19 @@ export const putHost = (
};
export const getPutHostMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof putHost>>,
TError,
{ data: BodyType<ZeustypesPostableHostDTO> },
{ data: ZeustypesPostableHostDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof putHost>>,
TError,
{ data: BodyType<ZeustypesPostableHostDTO> },
{ data: ZeustypesPostableHostDTO },
TContext
> => {
const mutationKey = ['putHost'];
@@ -150,7 +147,7 @@ export const getPutHostMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof putHost>>,
{ data: BodyType<ZeustypesPostableHostDTO> }
{ data: ZeustypesPostableHostDTO }
> = (props) => {
const { data } = props ?? {};
@@ -163,26 +160,26 @@ export const getPutHostMutationOptions = <
export type PutHostMutationResult = NonNullable<
Awaited<ReturnType<typeof putHost>>
>;
export type PutHostMutationBody = BodyType<ZeustypesPostableHostDTO>;
export type PutHostMutationError = ErrorType<RenderErrorResponseDTO>;
export type PutHostMutationBody = ZeustypesPostableHostDTO;
export type PutHostMutationError = RenderErrorResponseDTO;
/**
* @summary Put host in Zeus for a deployment.
*/
export const usePutHost = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof putHost>>,
TError,
{ data: BodyType<ZeustypesPostableHostDTO> },
{ data: ZeustypesPostableHostDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof putHost>>,
TError,
{ data: BodyType<ZeustypesPostableHostDTO> },
{ data: ZeustypesPostableHostDTO },
TContext
> => {
const mutationOptions = getPutHostMutationOptions(options);
@@ -194,7 +191,7 @@ export const usePutHost = <
* @summary Put profile in Zeus for a deployment.
*/
export const putProfile = (
zeustypesPostableProfileDTO: BodyType<ZeustypesPostableProfileDTO>,
zeustypesPostableProfileDTO: ZeustypesPostableProfileDTO,
) => {
return GeneratedAPIInstance<void>({
url: `/api/v2/zeus/profiles`,
@@ -205,19 +202,19 @@ export const putProfile = (
};
export const getPutProfileMutationOptions = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof putProfile>>,
TError,
{ data: BodyType<ZeustypesPostableProfileDTO> },
{ data: ZeustypesPostableProfileDTO },
TContext
>;
}): UseMutationOptions<
Awaited<ReturnType<typeof putProfile>>,
TError,
{ data: BodyType<ZeustypesPostableProfileDTO> },
{ data: ZeustypesPostableProfileDTO },
TContext
> => {
const mutationKey = ['putProfile'];
@@ -231,7 +228,7 @@ export const getPutProfileMutationOptions = <
const mutationFn: MutationFunction<
Awaited<ReturnType<typeof putProfile>>,
{ data: BodyType<ZeustypesPostableProfileDTO> }
{ data: ZeustypesPostableProfileDTO }
> = (props) => {
const { data } = props ?? {};
@@ -244,26 +241,26 @@ export const getPutProfileMutationOptions = <
export type PutProfileMutationResult = NonNullable<
Awaited<ReturnType<typeof putProfile>>
>;
export type PutProfileMutationBody = BodyType<ZeustypesPostableProfileDTO>;
export type PutProfileMutationError = ErrorType<RenderErrorResponseDTO>;
export type PutProfileMutationBody = ZeustypesPostableProfileDTO;
export type PutProfileMutationError = RenderErrorResponseDTO;
/**
* @summary Put profile in Zeus for a deployment.
*/
export const usePutProfile = <
TError = ErrorType<RenderErrorResponseDTO>,
TError = RenderErrorResponseDTO,
TContext = unknown
>(options?: {
mutation?: UseMutationOptions<
Awaited<ReturnType<typeof putProfile>>,
TError,
{ data: BodyType<ZeustypesPostableProfileDTO> },
{ data: ZeustypesPostableProfileDTO },
TContext
>;
}): UseMutationResult<
Awaited<ReturnType<typeof putProfile>>,
TError,
{ data: BodyType<ZeustypesPostableProfileDTO> },
{ data: ZeustypesPostableProfileDTO },
TContext
> => {
const mutationOptions = getPutProfileMutationOptions(options);

View File

@@ -1,27 +0,0 @@
import {
interceptorRejected,
interceptorsRequestResponse,
interceptorsResponse,
} from 'api';
import axios, { AxiosError, AxiosRequestConfig } from 'axios';
import { ENVIRONMENT } from 'constants/env';
// generated API Instance
const generatedAPIAxiosInstance = axios.create({
baseURL: ENVIRONMENT.baseURL,
});
export const GeneratedAPIInstance = <T>(
config: AxiosRequestConfig,
): Promise<T> => {
return generatedAPIAxiosInstance({ ...config }).then(({ data }) => data);
};
generatedAPIAxiosInstance.interceptors.request.use(interceptorsRequestResponse);
generatedAPIAxiosInstance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,
);
export type ErrorType<Error> = AxiosError<Error>;
export type BodyType<BodyData> = BodyData;

View File

@@ -28,7 +28,7 @@ const queryClient = new QueryClient({
},
});
export const interceptorsResponse = (
const interceptorsResponse = (
value: AxiosResponse<any>,
): Promise<AxiosResponse<any>> => {
if ((value.config as any)?.metadata) {
@@ -51,7 +51,7 @@ export const interceptorsResponse = (
return Promise.resolve(value);
};
export const interceptorsRequestResponse = (
const interceptorsRequestResponse = (
value: InternalAxiosRequestConfig,
): InternalAxiosRequestConfig => {
// Attach metadata safely (not sent with the request)
@@ -69,7 +69,7 @@ export const interceptorsRequestResponse = (
return value;
};
export const interceptorRejected = async (
const interceptorRejected = async (
value: AxiosResponse<any>,
): Promise<AxiosResponse<any>> => {
try {
@@ -203,6 +203,17 @@ LogEventAxiosInstance.interceptors.response.use(
LogEventAxiosInstance.interceptors.request.use(interceptorsRequestResponse);
//
// generated API Instance
export const GeneratedAPIInstance = axios.create({
baseURL: ENVIRONMENT.baseURL,
});
GeneratedAPIInstance.interceptors.request.use(interceptorsRequestResponse);
GeneratedAPIInstance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,
);
AxiosAlertManagerInstance.interceptors.response.use(
interceptorsResponse,
interceptorRejected,

View File

@@ -81,14 +81,14 @@ export default function CustomDomainSettings(): JSX.Element {
}, [hosts]);
useEffect(() => {
if (isFetchingHosts || !hostsData) {
if (isFetchingHosts) {
return;
}
if (hostsData.status === 'success') {
setHosts(hostsData.data.hosts ?? null);
if (hostsData?.data?.status === 'success') {
setHosts(hostsData?.data?.data?.hosts ?? null);
const activeCustomDomain = hostsData.data.hosts?.find(
const activeCustomDomain = hostsData?.data?.data?.hosts?.find(
(host) => !host.is_default,
);
@@ -99,13 +99,13 @@ export default function CustomDomainSettings(): JSX.Element {
}
}
if (hostsData.data.state !== 'HEALTHY' && isPollingEnabled) {
if (hostsData?.data?.data?.state !== 'HEALTHY' && isPollingEnabled) {
setTimeout(() => {
refetchHosts();
}, 3000);
}
if (hostsData.data.state === 'HEALTHY') {
if (hostsData?.data?.data?.state === 'HEALTHY') {
setIsPollingEnabled(false);
}
}, [hostsData, refetchHosts, isPollingEnabled, isFetchingHosts]);

View File

@@ -3,11 +3,13 @@ import { Button } from '@signozhq/button';
import { ArrowLeft, ArrowRight } from '@signozhq/icons';
import { Input } from '@signozhq/input';
import { Form, Select } from 'antd';
import { ErrorResponseHandlerForGeneratedAPIs } from 'api/ErrorResponseHandlerForGeneratedAPIs';
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
import { useForgotPassword } from 'api/generated/services/users';
import { AxiosError } from 'axios';
import AuthError from 'components/AuthError/AuthError';
import ROUTES from 'constants/routes';
import history from 'lib/history';
import { ErrorV2Resp } from 'types/api';
import APIError from 'types/api/error';
import { OrgSessionContext } from 'types/api/v2/sessions/context/get';
@@ -46,7 +48,7 @@ function ForgotPassword({
}
try {
ErrorResponseHandlerForGeneratedAPIs(mutationError);
ErrorResponseHandlerV2(mutationError as AxiosError<ErrorV2Resp>);
} catch (apiError) {
return apiError as APIError;
}

View File

@@ -34,7 +34,7 @@ function DataSourceInfo({
useEffect(() => {
if (hostsData) {
const defaultHost = hostsData?.data.hosts?.find((h) => h.is_default);
const defaultHost = hostsData?.data?.data?.hosts?.find((h) => h.is_default);
if (defaultHost?.url) {
const url = defaultHost?.url?.split('://')[1] ?? '';
setUrl(url);

View File

@@ -335,14 +335,14 @@ function MultiIngestionSettings(): JSX.Element {
const isError = isSearching ? isSearchError : isGetError;
useEffect(() => {
setDataSource(ingestionKeys?.data.keys || []);
setTotalIngestionKeys(ingestionKeys?.data._pagination?.total || 0);
setDataSource(ingestionKeys?.data.data?.keys || []);
setTotalIngestionKeys(ingestionKeys?.data?.data?._pagination?.total || 0);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [ingestionKeys?.data]);
}, [ingestionKeys?.data?.data]);
useEffect(() => {
if (isError && error) {
showErrorNotification(notifications, error);
if (isError) {
showErrorNotification(notifications, error as AxiosError);
}
}, [error, isError, notifications]);

View File

@@ -0,0 +1,34 @@
import { Color } from '@signozhq/design-tokens';
import { getColorsForSeverityLabels, isRedLike } from '../utils';
describe('getColorsForSeverityLabels', () => {
it('should return slate for blank labels', () => {
expect(getColorsForSeverityLabels('', 0)).toBe(Color.BG_SLATE_300);
expect(getColorsForSeverityLabels(' ', 0)).toBe(Color.BG_SLATE_300);
});
it('should return correct colors for known severity variants', () => {
expect(getColorsForSeverityLabels('INFO', 0)).toBe(Color.BG_ROBIN_600);
expect(getColorsForSeverityLabels('ERROR', 0)).toBe(Color.BG_CHERRY_600);
expect(getColorsForSeverityLabels('WARN', 0)).toBe(Color.BG_AMBER_600);
expect(getColorsForSeverityLabels('DEBUG', 0)).toBe(Color.BG_AQUA_600);
expect(getColorsForSeverityLabels('TRACE', 0)).toBe(Color.BG_FOREST_600);
expect(getColorsForSeverityLabels('FATAL', 0)).toBe(Color.BG_SAKURA_600);
});
it('should return non-red colors for unrecognized labels at any index', () => {
for (let i = 0; i < 30; i++) {
const color = getColorsForSeverityLabels('4', i);
expect(isRedLike(color)).toBe(false);
}
});
it('should return non-red colors for numeric severity text', () => {
const numericLabels = ['1', '2', '4', '9', '13', '17', '21'];
numericLabels.forEach((label) => {
const color = getColorsForSeverityLabels(label, 0);
expect(isRedLike(color)).toBe(false);
});
});
});

View File

@@ -1,7 +1,16 @@
import { Color } from '@signozhq/design-tokens';
import { themeColors } from 'constants/theme';
import { colors } from 'lib/getRandomColor';
// Function to determine if a color is "red-like" based on its RGB values
export function isRedLike(hex: string): boolean {
const r = parseInt(hex.slice(1, 3), 16);
const g = parseInt(hex.slice(3, 5), 16);
const b = parseInt(hex.slice(5, 7), 16);
return r > 180 && r > g * 1.4 && r > b * 1.4;
}
const SAFE_FALLBACK_COLORS = colors.filter((c) => !isRedLike(c));
const SEVERITY_VARIANT_COLORS: Record<string, string> = {
TRACE: Color.BG_FOREST_600,
Trace: Color.BG_FOREST_500,
@@ -67,8 +76,13 @@ export function getColorsForSeverityLabels(
label: string,
index: number,
): string {
// Check if we have a direct mapping for this severity variant
const variantColor = SEVERITY_VARIANT_COLORS[label.trim()];
const trimmed = label.trim();
if (!trimmed) {
return Color.BG_SLATE_300;
}
const variantColor = SEVERITY_VARIANT_COLORS[trimmed];
if (variantColor) {
return variantColor;
}
@@ -103,5 +117,8 @@ export function getColorsForSeverityLabels(
return Color.BG_SAKURA_500;
}
return colors[index % colors.length] || themeColors.red;
return (
SAFE_FALLBACK_COLORS[index % SAFE_FALLBACK_COLORS.length] ||
Color.BG_SLATE_400
);
}

View File

@@ -8,7 +8,7 @@ import logEvent from 'api/common/logEvent';
import inviteUsers from 'api/v1/invite/bulk/create';
import AuthError from 'components/AuthError/AuthError';
import { useNotifications } from 'hooks/useNotifications';
import { cloneDeep, debounce } from 'lodash-es';
import { cloneDeep, debounce, isEmpty } from 'lodash-es';
import {
ArrowRight,
ChevronDown,
@@ -65,7 +65,7 @@ function InviteTeamMembers({
};
useEffect(() => {
if (teamMembers === null) {
if (isEmpty(teamMembers)) {
const initialTeamMembers = Array.from({ length: 3 }, () => ({
...defaultTeamMember,
id: uuid(),
@@ -88,10 +88,7 @@ function InviteTeamMembers({
setTeamMembersToInvite((prev) => (prev || []).filter((m) => m.id !== id));
};
const isMemberTouched = (member: TeamMember): boolean =>
member.email.trim() !== '' ||
Boolean(member.role && member.role.trim() !== '');
// Validation function to check all users
const validateAllUsers = (): boolean => {
let isValid = true;
let hasEmailErrors = false;
@@ -99,9 +96,7 @@ function InviteTeamMembers({
const updatedEmailValidity: Record<string, boolean> = {};
const touchedMembers = teamMembersToInvite?.filter(isMemberTouched) ?? [];
touchedMembers?.forEach((member) => {
teamMembersToInvite?.forEach((member) => {
const emailValid = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(member.email);
const roleValid = Boolean(member.role && member.role.trim() !== '');
@@ -155,12 +150,12 @@ function InviteTeamMembers({
const handleNext = (): void => {
if (validateAllUsers()) {
setTeamMembers(teamMembersToInvite?.filter(isMemberTouched) ?? []);
setTeamMembers(teamMembersToInvite || []);
setHasInvalidEmails(false);
setHasInvalidRoles(false);
setInviteError(null);
sendInvites({
invites: teamMembersToInvite?.filter(isMemberTouched) ?? [],
invites: teamMembersToInvite || [],
});
}
};
@@ -235,12 +230,12 @@ function InviteTeamMembers({
const getValidationErrorMessage = (): string => {
if (hasInvalidEmails && hasInvalidRoles) {
return 'Please enter valid emails and select roles for team members';
return 'Please enter valid emails and select roles for all team members';
}
if (hasInvalidEmails) {
return 'Please enter valid emails for team members';
return 'Please enter valid emails for all team members';
}
return 'Please select roles for team members';
return 'Please select roles for all team members';
};
const handleDoLater = (): void => {
@@ -251,10 +246,7 @@ function InviteTeamMembers({
onNext();
};
const hasInvites =
(teamMembersToInvite?.filter(isMemberTouched) ?? []).length > 0;
const isButtonDisabled = isSendingInvites || isLoading;
const isInviteButtonDisabled = isButtonDisabled || !hasInvites;
return (
<div className="questions-container">
@@ -364,11 +356,9 @@ function InviteTeamMembers({
<Button
variant="solid"
color="primary"
className={`onboarding-next-button ${
isInviteButtonDisabled ? 'disabled' : ''
}`}
className={`onboarding-next-button ${isButtonDisabled ? 'disabled' : ''}`}
onClick={handleNext}
disabled={isInviteButtonDisabled}
disabled={isButtonDisabled}
suffixIcon={
isButtonDisabled ? (
<Loader2 className="animate-spin" size={12} />
@@ -377,7 +367,7 @@ function InviteTeamMembers({
)
}
>
Send Invites
Complete
</Button>
<Button
variant="ghost"

View File

@@ -1,480 +0,0 @@
import { rest, server } from 'mocks-server/server';
import {
fireEvent,
render,
screen,
userEvent,
waitFor,
} from 'tests/test-utils';
import InviteTeamMembers from '../InviteTeamMembers';
jest.mock('api/common/logEvent', () => ({
__esModule: true,
default: jest.fn(),
}));
const mockNotificationSuccess = jest.fn() as jest.MockedFunction<
(args: { message: string }) => void
>;
const mockNotificationError = jest.fn() as jest.MockedFunction<
(args: { message: string }) => void
>;
jest.mock('hooks/useNotifications', () => ({
useNotifications: (): any => ({
notifications: {
success: mockNotificationSuccess,
error: mockNotificationError,
},
}),
}));
const INVITE_USERS_ENDPOINT = '*/api/v1/invite/bulk';
interface TeamMember {
email: string;
role: string;
name: string;
frontendBaseUrl: string;
id: string;
}
interface InviteRequestBody {
invites: { email: string; role: string }[];
}
interface RenderProps {
isLoading?: boolean;
teamMembers?: TeamMember[] | null;
}
const mockOnNext = jest.fn() as jest.MockedFunction<() => void>;
const mockSetTeamMembers = jest.fn() as jest.MockedFunction<
(members: TeamMember[]) => void
>;
function renderComponent({
isLoading = false,
teamMembers = null,
}: RenderProps = {}): ReturnType<typeof render> {
return render(
<InviteTeamMembers
isLoading={isLoading}
teamMembers={teamMembers}
setTeamMembers={mockSetTeamMembers}
onNext={mockOnNext}
/>,
);
}
async function selectRole(
user: ReturnType<typeof userEvent.setup>,
selectIndex: number,
optionLabel: string,
): Promise<void> {
const placeholders = screen.getAllByText(/select roles/i);
await user.click(placeholders[selectIndex]);
const optionContent = await screen.findByText(optionLabel);
fireEvent.click(optionContent);
}
describe('InviteTeamMembers', () => {
beforeEach(() => {
jest.clearAllMocks();
server.use(
rest.post(INVITE_USERS_ENDPOINT, (_, res, ctx) =>
res(ctx.status(200), ctx.json({ status: 'success' })),
),
);
});
afterEach(() => {
jest.useRealTimers();
server.resetHandlers();
});
describe('Initial rendering', () => {
it('renders the page header, column labels, default rows, and action buttons', () => {
renderComponent();
expect(
screen.getByRole('heading', { name: /invite your team/i }),
).toBeInTheDocument();
expect(
screen.getByText(/signoz is a lot more useful with collaborators/i),
).toBeInTheDocument();
expect(
screen.getAllByPlaceholderText(/e\.g\. john@signoz\.io/i),
).toHaveLength(3);
expect(screen.getByText('Email address')).toBeInTheDocument();
expect(screen.getByText('Roles')).toBeInTheDocument();
expect(
screen.getByRole('button', { name: /send invites/i }),
).toBeInTheDocument();
expect(
screen.getByRole('button', { name: /i'll do this later/i }),
).toBeInTheDocument();
});
it('disables both action buttons while isLoading is true', () => {
renderComponent({ isLoading: true });
expect(screen.getByRole('button', { name: /send invites/i })).toBeDisabled();
expect(
screen.getByRole('button', { name: /i'll do this later/i }),
).toBeDisabled();
});
});
describe('Row management', () => {
it('adds a new empty row when "Add another" is clicked', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
expect(
screen.getAllByPlaceholderText(/e\.g\. john@signoz\.io/i),
).toHaveLength(3);
await user.click(screen.getByRole('button', { name: /add another/i }));
expect(
screen.getAllByPlaceholderText(/e\.g\. john@signoz\.io/i),
).toHaveLength(4);
});
it('removes the correct row when its trash icon is clicked', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
const emailInputs = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(emailInputs[0], 'first@example.com');
await screen.findByDisplayValue('first@example.com');
await user.click(
screen.getAllByRole('button', { name: /remove team member/i })[0],
);
await waitFor(() => {
expect(
screen.queryByDisplayValue('first@example.com'),
).not.toBeInTheDocument();
expect(
screen.getAllByPlaceholderText(/e\.g\. john@signoz\.io/i),
).toHaveLength(2);
});
});
it('hides remove buttons when only one row remains', async () => {
renderComponent();
const user = userEvent.setup({ pointerEventsCheck: 0 });
let removeButtons = screen.getAllByRole('button', {
name: /remove team member/i,
});
while (removeButtons.length > 0) {
await user.click(removeButtons[0]);
removeButtons = screen.queryAllByRole('button', {
name: /remove team member/i,
});
}
expect(
screen.queryByRole('button', { name: /remove team member/i }),
).not.toBeInTheDocument();
});
});
describe('Inline email validation', () => {
it('shows an inline error after typing an invalid email and clears it when a valid email is entered', async () => {
jest.useFakeTimers();
const user = userEvent.setup({
advanceTimers: (ms) => jest.advanceTimersByTime(ms),
});
renderComponent();
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, 'not-an-email');
jest.advanceTimersByTime(600);
await waitFor(() => {
expect(screen.getByText(/invalid email address/i)).toBeInTheDocument();
});
await user.clear(firstInput);
await user.type(firstInput, 'good@example.com');
jest.advanceTimersByTime(600);
await waitFor(() => {
expect(
screen.queryByText(/invalid email address/i),
).not.toBeInTheDocument();
});
});
it('does not show an inline error when the field is cleared back to empty', async () => {
jest.useFakeTimers();
const user = userEvent.setup({
advanceTimers: (ms) => jest.advanceTimersByTime(ms),
});
renderComponent();
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, 'a');
await user.clear(firstInput);
jest.advanceTimersByTime(600);
await waitFor(() => {
expect(
screen.queryByText(/invalid email address/i),
).not.toBeInTheDocument();
});
});
});
describe('Validation callout on Complete', () => {
it('shows the correct callout message for each combination of email/role validity', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
const removeButtons = screen.getAllByRole('button', {
name: /remove team member/i,
});
await user.click(removeButtons[0]);
await user.click(
screen.getAllByRole('button', { name: /remove team member/i })[0],
);
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, 'bad-email');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(
screen.getByText(
/please enter valid emails and select roles for team members/i,
),
).toBeInTheDocument();
expect(
screen.queryByText(/please enter valid emails for team members/i),
).not.toBeInTheDocument();
expect(
screen.queryByText(/please select roles for team members/i),
).not.toBeInTheDocument();
});
await selectRole(user, 0, 'Viewer');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(
screen.getByText(/please enter valid emails for team members/i),
).toBeInTheDocument();
expect(
screen.queryByText(/please select roles for team members/i),
).not.toBeInTheDocument();
expect(
screen.queryByText(/please enter valid emails and select roles/i),
).not.toBeInTheDocument();
});
await user.clear(firstInput);
await user.type(firstInput, 'valid@example.com');
await user.click(screen.getByRole('button', { name: /add another/i }));
const allInputs = screen.getAllByPlaceholderText(/e\.g\. john@signoz\.io/i);
await user.type(allInputs[1], 'norole@example.com');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(
screen.getByText(/please select roles for team members/i),
).toBeInTheDocument();
expect(
screen.queryByText(/please enter valid emails for team members/i),
).not.toBeInTheDocument();
expect(
screen.queryByText(/please enter valid emails and select roles/i),
).not.toBeInTheDocument();
});
});
it('treats whitespace as untouched, clears the callout on fix-and-resubmit, and clears role error on role select', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
const removeButtons = screen.getAllByRole('button', {
name: /remove team member/i,
});
await user.click(removeButtons[0]);
await user.click(
screen.getAllByRole('button', { name: /remove team member/i })[0],
);
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, ' ');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(
screen.queryByText(/please enter valid emails/i),
).not.toBeInTheDocument();
expect(screen.queryByText(/please select roles/i)).not.toBeInTheDocument();
});
await user.clear(firstInput);
await user.type(firstInput, 'bad-email');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(
screen.getByText(
/please enter valid emails and select roles for team members/i,
),
).toBeInTheDocument();
expect(
screen.queryByText(/please enter valid emails for team members/i),
).not.toBeInTheDocument();
expect(
screen.queryByText(/please select roles for team members/i),
).not.toBeInTheDocument();
});
await user.clear(firstInput);
await user.type(firstInput, 'good@example.com');
await selectRole(user, 0, 'Admin');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(
screen.queryByText(/please enter valid emails and select roles/i),
).not.toBeInTheDocument();
expect(
screen.queryByText(/please enter valid emails for team members/i),
).not.toBeInTheDocument();
expect(
screen.queryByText(/please select roles for team members/i),
).not.toBeInTheDocument();
});
await waitFor(() => expect(mockOnNext).toHaveBeenCalledTimes(1), {
timeout: 1200,
});
});
it('disables the Send Invites button when all rows are untouched (empty)', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
const sendInvitesBtn = screen.getByRole('button', { name: /send invites/i });
expect(sendInvitesBtn).toBeDisabled();
// Type something to make a row touched
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, 'a');
expect(sendInvitesBtn).not.toBeDisabled();
});
});
describe('API integration', () => {
it('only sends touched (non-empty) rows — empty rows are excluded from the invite payload', async () => {
let capturedBody: InviteRequestBody | null = null;
server.use(
rest.post(INVITE_USERS_ENDPOINT, async (req, res, ctx) => {
capturedBody = await req.json<InviteRequestBody>();
return res(ctx.status(200), ctx.json({ status: 'success' }));
}),
);
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, 'only@example.com');
await selectRole(user, 0, 'Admin');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(capturedBody).not.toBeNull();
expect(capturedBody?.invites).toHaveLength(1);
expect(capturedBody?.invites[0]).toMatchObject({
email: 'only@example.com',
role: 'ADMIN',
});
});
await waitFor(() => expect(mockOnNext).toHaveBeenCalled(), {
timeout: 1200,
});
});
it('calls the invite API, shows a success notification, and calls onNext after the 1 s delay', async () => {
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, 'alice@example.com');
await selectRole(user, 0, 'Admin');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(mockNotificationSuccess).toHaveBeenCalledWith(
expect.objectContaining({ message: 'Invites sent successfully!' }),
);
});
await waitFor(
() => {
expect(mockOnNext).toHaveBeenCalledTimes(1);
},
{ timeout: 1200 },
);
});
it('renders an API error container when the invite request fails', async () => {
server.use(
rest.post(INVITE_USERS_ENDPOINT, (_, res, ctx) =>
res(
ctx.status(500),
ctx.json({
errors: [{ code: 'INTERNAL_ERROR', msg: 'Something went wrong' }],
}),
),
),
);
const user = userEvent.setup({ pointerEventsCheck: 0 });
renderComponent();
const [firstInput] = screen.getAllByPlaceholderText(
/e\.g\. john@signoz\.io/i,
);
await user.type(firstInput, 'fail@example.com');
await selectRole(user, 0, 'Viewer');
await user.click(screen.getByRole('button', { name: /send invites/i }));
await waitFor(() => {
expect(document.querySelector('.auth-error-container')).toBeInTheDocument();
});
await user.type(firstInput, 'x');
await waitFor(() => {
expect(
document.querySelector('.auth-error-container'),
).not.toBeInTheDocument();
});
});
});
});

View File

@@ -3,7 +3,11 @@ import { useCopyToClipboard } from 'react-use';
import { Button, Skeleton, Tooltip, Typography } from 'antd';
import logEvent from 'api/common/logEvent';
import { useGetIngestionKeys } from 'api/generated/services/gateway';
import { GatewaytypesIngestionKeyDTO } from 'api/generated/services/sigNoz.schemas';
import {
GatewaytypesIngestionKeyDTO,
RenderErrorResponseDTO,
} from 'api/generated/services/sigNoz.schemas';
import { AxiosError } from 'axios';
import { DOCS_BASE_URL } from 'constants/app';
import { useGetGlobalConfig } from 'hooks/globalConfig/useGetGlobalConfig';
import { useNotifications } from 'hooks/useNotifications';
@@ -68,21 +72,24 @@ export default function OnboardingIngestionDetails(): JSX.Element {
};
useEffect(() => {
if (!ingestionKeys || isIngestionKeysLoading) {
return;
if (
ingestionKeys?.data?.data?.keys &&
ingestionKeys?.data.data.keys.length > 0
) {
setFirstIngestionKey(ingestionKeys?.data.data.keys[0]);
}
if (ingestionKeys.data.keys && ingestionKeys.data.keys.length > 0) {
setFirstIngestionKey(ingestionKeys.data.keys[0]);
}
}, [isIngestionKeysLoading, ingestionKeys]);
}, [ingestionKeys]);
return (
<div className="configure-product-ingestion-section-content">
{isError && (
<div className="ingestion-endpoint-section-error-container">
<Typography.Text className="ingestion-endpoint-section-error-text error">
<TriangleAlert size={14} /> {error.message || 'Something went wrong'}
<TriangleAlert size={14} />{' '}
{(error as AxiosError<RenderErrorResponseDTO>)?.response?.data?.error
?.message ||
(error as AxiosError)?.message ||
'Something went wrong'}
</Typography.Text>
<div className="ingestion-setup-details-links">

View File

@@ -6,7 +6,7 @@ import { toast } from '@signozhq/sonner';
import { Modal } from 'antd';
import { Table } from 'antd';
import { ColumnsType } from 'antd/lib/table';
import { ErrorResponseHandlerForGeneratedAPIs } from 'api/ErrorResponseHandlerForGeneratedAPIs';
import { ErrorResponseHandlerV2 } from 'api/ErrorResponseHandlerV2';
import {
useDeleteAuthDomain,
useListAuthDomains,
@@ -19,6 +19,7 @@ import { AxiosError } from 'axios';
import ErrorContent from 'components/ErrorModal/components/ErrorContent';
import CopyToClipboard from 'periscope/components/CopyToClipboard';
import { useErrorModal } from 'providers/ErrorModalProvider';
import { ErrorV2Resp } from 'types/api';
import APIError from 'types/api/error';
import CreateEdit from './CreateEdit/CreateEdit';
@@ -85,7 +86,7 @@ function AuthDomain(): JSX.Element {
},
onError: (error) => {
try {
ErrorResponseHandlerForGeneratedAPIs(error);
ErrorResponseHandlerV2(error as AxiosError<ErrorV2Resp>);
} catch (apiError) {
showErrorModal(apiError as APIError);
}
@@ -108,7 +109,9 @@ function AuthDomain(): JSX.Element {
let errorResult: APIError | null = null;
try {
ErrorResponseHandlerForGeneratedAPIs(errorFetchingAuthDomainListResponse);
ErrorResponseHandlerV2(
errorFetchingAuthDomainListResponse as AxiosError<ErrorV2Resp>,
);
} catch (error) {
errorResult = error as APIError;
}
@@ -199,7 +202,7 @@ function AuthDomain(): JSX.Element {
{!errorFetchingAuthDomainListResponse && (
<Table
columns={columns}
dataSource={authDomainListResponse?.data}
dataSource={authDomainListResponse?.data?.data}
onRow={undefined}
loading={
isLoadingAuthDomainListResponse || isFetchingAuthDomainListResponse

View File

@@ -40,7 +40,7 @@ function RolesListingTable({
[history, urlQuery],
);
const roles = useMemo(() => data?.data ?? [], [data]);
const roles = useMemo(() => data?.data?.data ?? [], [data]);
const formatTimestamp = (date?: Date | string): string => {
if (!date) {

View File

@@ -6,8 +6,8 @@ import (
)
type JSON struct {
Code string `json:"code" required:"true"`
Message string `json:"message" required:"true"`
Code string `json:"code"`
Message string `json:"message"`
Url string `json:"url,omitempty"`
Errors []responseerroradditional `json:"errors,omitempty"`
}

View File

@@ -1,44 +0,0 @@
package middleware
import (
"log/slog"
"net/http"
"runtime/debug"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/http/render"
)
// Recovery is a middleware that recovers from panics, logs the panic,
// and returns a 500 Internal Server Error.
type Recovery struct {
logger *slog.Logger
}
// NewRecovery creates a new Recovery middleware.
func NewRecovery(logger *slog.Logger) Wrapper {
return &Recovery{
logger: logger.With("pkg", "http-middleware-recovery"),
}
}
// Wrap is the middleware handler.
func (m *Recovery) Wrap(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if err := recover(); err != nil {
m.logger.ErrorContext(
r.Context(),
"panic recovered",
"err", err, "stack", string(debug.Stack()),
)
render.Error(w, errors.NewInternalf(
errors.CodeInternal, "internal server error",
))
}
}()
next.ServeHTTP(w, r)
})
}

View File

@@ -16,13 +16,13 @@ const (
var json = jsoniter.ConfigCompatibleWithStandardLibrary
type SuccessResponse struct {
Status string `json:"status" required:"true"`
Data interface{} `json:"data,omitempty" required:"true"`
Status string `json:"status"`
Data interface{} `json:"data,omitempty"`
}
type ErrorResponse struct {
Status string `json:"status" required:"true"`
Error *errors.JSON `json:"error" required:"true"`
Status string `json:"status"`
Error *errors.JSON `json:"error"`
}
func Success(rw http.ResponseWriter, httpCode int, data interface{}) {

View File

@@ -13,7 +13,6 @@ import (
root "github.com/SigNoz/signoz/pkg/modules/user"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/gorilla/mux"
)
@@ -463,7 +462,7 @@ func (h *handler) UpdateAPIKey(w http.ResponseWriter, r *http.Request) {
return
}
if slices.Contains(integrationtypes.IntegrationUserEmails, createdByUser.Email) {
if slices.Contains(types.AllIntegrationUserEmails, types.IntegrationUserEmail(createdByUser.Email.String())) {
render.Error(w, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "API Keys for integration users cannot be revoked"))
return
}
@@ -508,7 +507,7 @@ func (h *handler) RevokeAPIKey(w http.ResponseWriter, r *http.Request) {
return
}
if slices.Contains(integrationtypes.IntegrationUserEmails, createdByUser.Email) {
if slices.Contains(types.AllIntegrationUserEmails, types.IntegrationUserEmail(createdByUser.Email.String())) {
render.Error(w, errors.Newf(errors.TypeInvalidInput, errors.CodeInvalidInput, "API Keys for integration users cannot be revoked"))
return
}

View File

@@ -19,7 +19,6 @@ import (
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/authtypes"
"github.com/SigNoz/signoz/pkg/types/emailtypes"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/types/roletypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/dustin/go-humanize"
@@ -174,7 +173,7 @@ func (m *Module) DeleteInvite(ctx context.Context, orgID string, id valuer.UUID)
func (module *Module) CreateUser(ctx context.Context, input *types.User, opts ...root.CreateUserOption) error {
createUserOpts := root.NewCreateUserOptions(opts...)
// since assign is idempotent multiple calls to assign won't cause issues in case of retries.
// since assign is idempotant multiple calls to assign won't cause issues in case of retries.
err := module.authz.Grant(ctx, input.OrgID, roletypes.MustGetSigNozManagedRoleFromExistingRole(input.Role), authtypes.MustNewSubject(authtypes.TypeableUser, input.ID.StringValue(), input.OrgID, nil))
if err != nil {
return err
@@ -280,7 +279,7 @@ func (module *Module) DeleteUser(ctx context.Context, orgID valuer.UUID, id stri
return errors.WithAdditionalf(err, "cannot delete root user")
}
if slices.Contains(integrationtypes.IntegrationUserEmails, user.Email) {
if slices.Contains(types.AllIntegrationUserEmails, types.IntegrationUserEmail(user.Email.String())) {
return errors.New(errors.TypeForbidden, errors.CodeForbidden, "integration user cannot be deleted")
}
@@ -294,7 +293,7 @@ func (module *Module) DeleteUser(ctx context.Context, orgID valuer.UUID, id stri
return errors.New(errors.TypeForbidden, errors.CodeForbidden, "cannot delete the last admin")
}
// since revoke is idempotent multiple calls to revoke won't cause issues in case of retries
// since revoke is idempotant multiple calls to revoke won't cause issues in case of retries
err = module.authz.Revoke(ctx, orgID, roletypes.MustGetSigNozManagedRoleFromExistingRole(user.Role), authtypes.MustNewSubject(authtypes.TypeableUser, id, orgID, nil))
if err != nil {
return err

View File

@@ -1,57 +1,55 @@
package store
package cloudintegrations
import (
"context"
"database/sql"
"fmt"
"log/slog"
"strings"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
var (
CodeCloudIntegrationAccountNotFound errors.Code = errors.MustNewCode("cloud_integration_account_not_found")
)
type cloudProviderAccountsRepository interface {
listConnected(ctx context.Context, orgId string, provider string) ([]types.CloudIntegration, *model.ApiError)
type CloudProviderAccountsRepository interface {
ListConnected(ctx context.Context, orgId string, provider string) ([]integrationtypes.CloudIntegration, error)
get(ctx context.Context, orgId string, provider string, id string) (*types.CloudIntegration, *model.ApiError)
Get(ctx context.Context, orgId string, provider string, id string) (*integrationtypes.CloudIntegration, error)
GetConnectedCloudAccount(ctx context.Context, orgId, provider string, accountID string) (*integrationtypes.CloudIntegration, error)
getConnectedCloudAccount(ctx context.Context, orgId string, provider string, accountID string) (*types.CloudIntegration, *model.ApiError)
// Insert an account or update it by (cloudProvider, id)
// for specified non-empty fields
Upsert(
upsert(
ctx context.Context,
orgId string,
provider string,
id *string,
config []byte,
config *types.AccountConfig,
accountId *string,
agentReport *integrationtypes.AgentReport,
agentReport *types.AgentReport,
removedAt *time.Time,
) (*integrationtypes.CloudIntegration, error)
) (*types.CloudIntegration, *model.ApiError)
}
func NewCloudProviderAccountsRepository(store sqlstore.SQLStore) CloudProviderAccountsRepository {
return &cloudProviderAccountsSQLRepository{store: store}
func newCloudProviderAccountsRepository(store sqlstore.SQLStore) (
*cloudProviderAccountsSQLRepository, error,
) {
return &cloudProviderAccountsSQLRepository{
store: store,
}, nil
}
type cloudProviderAccountsSQLRepository struct {
store sqlstore.SQLStore
}
func (r *cloudProviderAccountsSQLRepository) ListConnected(
func (r *cloudProviderAccountsSQLRepository) listConnected(
ctx context.Context, orgId string, cloudProvider string,
) ([]integrationtypes.CloudIntegration, error) {
accounts := []integrationtypes.CloudIntegration{}
) ([]types.CloudIntegration, *model.ApiError) {
accounts := []types.CloudIntegration{}
err := r.store.BunDB().NewSelect().
Model(&accounts).
@@ -64,17 +62,18 @@ func (r *cloudProviderAccountsSQLRepository) ListConnected(
Scan(ctx)
if err != nil {
slog.ErrorContext(ctx, "error querying connected cloud accounts", "error", err)
return nil, errors.WrapInternalf(err, errors.CodeInternal, "could not query connected cloud accounts")
return nil, model.InternalError(fmt.Errorf(
"could not query connected cloud accounts: %w", err,
))
}
return accounts, nil
}
func (r *cloudProviderAccountsSQLRepository) Get(
func (r *cloudProviderAccountsSQLRepository) get(
ctx context.Context, orgId string, provider string, id string,
) (*integrationtypes.CloudIntegration, error) {
var result integrationtypes.CloudIntegration
) (*types.CloudIntegration, *model.ApiError) {
var result types.CloudIntegration
err := r.store.BunDB().NewSelect().
Model(&result).
@@ -83,25 +82,23 @@ func (r *cloudProviderAccountsSQLRepository) Get(
Where("id = ?", id).
Scan(ctx)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, errors.WrapNotFoundf(
err,
CodeCloudIntegrationAccountNotFound,
"couldn't find account with Id %s", id,
)
}
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't query cloud provider account")
if err == sql.ErrNoRows {
return nil, model.NotFoundError(fmt.Errorf(
"couldn't find account with Id %s", id,
))
} else if err != nil {
return nil, model.InternalError(fmt.Errorf(
"couldn't query cloud provider accounts: %w", err,
))
}
return &result, nil
}
func (r *cloudProviderAccountsSQLRepository) GetConnectedCloudAccount(
func (r *cloudProviderAccountsSQLRepository) getConnectedCloudAccount(
ctx context.Context, orgId string, provider string, accountId string,
) (*integrationtypes.CloudIntegration, error) {
var result integrationtypes.CloudIntegration
) (*types.CloudIntegration, *model.ApiError) {
var result types.CloudIntegration
err := r.store.BunDB().NewSelect().
Model(&result).
@@ -112,25 +109,29 @@ func (r *cloudProviderAccountsSQLRepository) GetConnectedCloudAccount(
Where("removed_at is NULL").
Scan(ctx)
if errors.Is(err, sql.ErrNoRows) {
return nil, errors.WrapNotFoundf(err, CodeCloudIntegrationAccountNotFound, "couldn't find connected cloud account %s", accountId)
if err == sql.ErrNoRows {
return nil, model.NotFoundError(fmt.Errorf(
"couldn't find connected cloud account %s", accountId,
))
} else if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't query cloud provider account")
return nil, model.InternalError(fmt.Errorf(
"couldn't query cloud provider accounts: %w", err,
))
}
return &result, nil
}
func (r *cloudProviderAccountsSQLRepository) Upsert(
func (r *cloudProviderAccountsSQLRepository) upsert(
ctx context.Context,
orgId string,
provider string,
id *string,
config []byte,
config *types.AccountConfig,
accountId *string,
agentReport *integrationtypes.AgentReport,
agentReport *types.AgentReport,
removedAt *time.Time,
) (*integrationtypes.CloudIntegration, error) {
) (*types.CloudIntegration, *model.ApiError) {
// Insert
if id == nil {
temp := valuer.GenerateUUID().StringValue()
@@ -180,7 +181,7 @@ func (r *cloudProviderAccountsSQLRepository) Upsert(
)
}
integration := integrationtypes.CloudIntegration{
integration := types.CloudIntegration{
OrgID: orgId,
Provider: provider,
Identifiable: types.Identifiable{ID: valuer.MustNewUUID(*id)},
@@ -188,25 +189,28 @@ func (r *cloudProviderAccountsSQLRepository) Upsert(
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
Config: string(config),
Config: config,
AccountID: accountId,
LastAgentReport: agentReport,
RemovedAt: removedAt,
}
_, err := r.store.BunDB().NewInsert().
_, dbErr := r.store.BunDB().NewInsert().
Model(&integration).
On(onConflictClause).
Exec(ctx)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't upsert cloud integration account")
if dbErr != nil {
return nil, model.InternalError(fmt.Errorf(
"could not upsert cloud account record: %w", dbErr,
))
}
upsertedAccount, err := r.Get(ctx, orgId, provider, *id)
if err != nil {
slog.ErrorContext(ctx, "error upserting cloud integration account", "error", err)
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't get upserted cloud integration account")
upsertedAccount, apiErr := r.get(ctx, orgId, provider, *id)
if apiErr != nil {
return nil, model.InternalError(fmt.Errorf(
"couldn't fetch upserted account by id: %w", apiErr.ToError(),
))
}
return upsertedAccount, nil

View File

@@ -1,4 +1,4 @@
package integrationtypes
package cloudintegrations
import (
"github.com/SigNoz/signoz/pkg/errors"

View File

@@ -0,0 +1,624 @@
package cloudintegrations
import (
"context"
"fmt"
"net/url"
"slices"
"strings"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations/services"
"github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"golang.org/x/exp/maps"
)
var SupportedCloudProviders = []string{
"aws",
}
func validateCloudProviderName(name string) *model.ApiError {
if !slices.Contains(SupportedCloudProviders, name) {
return model.BadRequest(fmt.Errorf("invalid cloud provider: %s", name))
}
return nil
}
type Controller struct {
accountsRepo cloudProviderAccountsRepository
serviceConfigRepo ServiceConfigDatabase
}
func NewController(sqlStore sqlstore.SQLStore) (*Controller, error) {
accountsRepo, err := newCloudProviderAccountsRepository(sqlStore)
if err != nil {
return nil, fmt.Errorf("couldn't create cloud provider accounts repo: %w", err)
}
serviceConfigRepo, err := newServiceConfigRepository(sqlStore)
if err != nil {
return nil, fmt.Errorf("couldn't create cloud provider service config repo: %w", err)
}
return &Controller{
accountsRepo: accountsRepo,
serviceConfigRepo: serviceConfigRepo,
}, nil
}
type ConnectedAccountsListResponse struct {
Accounts []types.Account `json:"accounts"`
}
func (c *Controller) ListConnectedAccounts(ctx context.Context, orgId string, cloudProvider string) (
*ConnectedAccountsListResponse, *model.ApiError,
) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
accountRecords, apiErr := c.accountsRepo.listConnected(ctx, orgId, cloudProvider)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't list cloud accounts")
}
connectedAccounts := []types.Account{}
for _, a := range accountRecords {
connectedAccounts = append(connectedAccounts, a.Account())
}
return &ConnectedAccountsListResponse{
Accounts: connectedAccounts,
}, nil
}
type GenerateConnectionUrlRequest struct {
// Optional. To be specified for updates.
AccountId *string `json:"account_id,omitempty"`
AccountConfig types.AccountConfig `json:"account_config"`
AgentConfig SigNozAgentConfig `json:"agent_config"`
}
type SigNozAgentConfig struct {
// The region in which SigNoz agent should be installed.
Region string `json:"region"`
IngestionUrl string `json:"ingestion_url"`
IngestionKey string `json:"ingestion_key"`
SigNozAPIUrl string `json:"signoz_api_url"`
SigNozAPIKey string `json:"signoz_api_key"`
Version string `json:"version,omitempty"`
}
type GenerateConnectionUrlResponse struct {
AccountId string `json:"account_id"`
ConnectionUrl string `json:"connection_url"`
}
func (c *Controller) GenerateConnectionUrl(ctx context.Context, orgId string, cloudProvider string, req GenerateConnectionUrlRequest) (*GenerateConnectionUrlResponse, *model.ApiError) {
// Account connection with a simple connection URL may not be available for all providers.
if cloudProvider != "aws" {
return nil, model.BadRequest(fmt.Errorf("unsupported cloud provider: %s", cloudProvider))
}
account, apiErr := c.accountsRepo.upsert(
ctx, orgId, cloudProvider, req.AccountId, &req.AccountConfig, nil, nil, nil,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't upsert cloud account")
}
agentVersion := "v0.0.8"
if req.AgentConfig.Version != "" {
agentVersion = req.AgentConfig.Version
}
connectionUrl := fmt.Sprintf(
"https://%s.console.aws.amazon.com/cloudformation/home?region=%s#/stacks/quickcreate?",
req.AgentConfig.Region, req.AgentConfig.Region,
)
for qp, value := range map[string]string{
"param_SigNozIntegrationAgentVersion": agentVersion,
"param_SigNozApiUrl": req.AgentConfig.SigNozAPIUrl,
"param_SigNozApiKey": req.AgentConfig.SigNozAPIKey,
"param_SigNozAccountId": account.ID.StringValue(),
"param_IngestionUrl": req.AgentConfig.IngestionUrl,
"param_IngestionKey": req.AgentConfig.IngestionKey,
"stackName": "signoz-integration",
"templateURL": fmt.Sprintf(
"https://signoz-integrations.s3.us-east-1.amazonaws.com/aws-quickcreate-template-%s.json",
agentVersion,
),
} {
connectionUrl += fmt.Sprintf("&%s=%s", qp, url.QueryEscape(value))
}
return &GenerateConnectionUrlResponse{
AccountId: account.ID.StringValue(),
ConnectionUrl: connectionUrl,
}, nil
}
type AccountStatusResponse struct {
Id string `json:"id"`
CloudAccountId *string `json:"cloud_account_id,omitempty"`
Status types.AccountStatus `json:"status"`
}
func (c *Controller) GetAccountStatus(ctx context.Context, orgId string, cloudProvider string, accountId string) (
*AccountStatusResponse, *model.ApiError,
) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
account, apiErr := c.accountsRepo.get(ctx, orgId, cloudProvider, accountId)
if apiErr != nil {
return nil, apiErr
}
resp := AccountStatusResponse{
Id: account.ID.StringValue(),
CloudAccountId: account.AccountID,
Status: account.Status(),
}
return &resp, nil
}
type AgentCheckInRequest struct {
ID string `json:"account_id"`
AccountID string `json:"cloud_account_id"`
// Arbitrary cloud specific Agent data
Data map[string]any `json:"data,omitempty"`
}
type AgentCheckInResponse struct {
AccountId string `json:"account_id"`
CloudAccountId string `json:"cloud_account_id"`
RemovedAt *time.Time `json:"removed_at"`
IntegrationConfig IntegrationConfigForAgent `json:"integration_config"`
}
type IntegrationConfigForAgent struct {
EnabledRegions []string `json:"enabled_regions"`
TelemetryCollectionStrategy *CompiledCollectionStrategy `json:"telemetry,omitempty"`
}
func (c *Controller) CheckInAsAgent(ctx context.Context, orgId string, cloudProvider string, req AgentCheckInRequest) (*AgentCheckInResponse, error) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
existingAccount, apiErr := c.accountsRepo.get(ctx, orgId, cloudProvider, req.ID)
if existingAccount != nil && existingAccount.AccountID != nil && *existingAccount.AccountID != req.AccountID {
return nil, model.BadRequest(fmt.Errorf(
"can't check in with new %s account id %s for account %s with existing %s id %s",
cloudProvider, req.AccountID, existingAccount.ID.StringValue(), cloudProvider, *existingAccount.AccountID,
))
}
existingAccount, apiErr = c.accountsRepo.getConnectedCloudAccount(ctx, orgId, cloudProvider, req.AccountID)
if existingAccount != nil && existingAccount.ID.StringValue() != req.ID {
return nil, model.BadRequest(fmt.Errorf(
"can't check in to %s account %s with id %s. already connected with id %s",
cloudProvider, req.AccountID, req.ID, existingAccount.ID.StringValue(),
))
}
agentReport := types.AgentReport{
TimestampMillis: time.Now().UnixMilli(),
Data: req.Data,
}
account, apiErr := c.accountsRepo.upsert(
ctx, orgId, cloudProvider, &req.ID, nil, &req.AccountID, &agentReport, nil,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't upsert cloud account")
}
// prepare and return integration config to be consumed by agent
compiledStrategy, err := NewCompiledCollectionStrategy(cloudProvider)
if err != nil {
return nil, model.InternalError(fmt.Errorf(
"couldn't init telemetry collection strategy: %w", err,
))
}
agentConfig := IntegrationConfigForAgent{
EnabledRegions: []string{},
TelemetryCollectionStrategy: compiledStrategy,
}
if account.Config != nil && account.Config.EnabledRegions != nil {
agentConfig.EnabledRegions = account.Config.EnabledRegions
}
services, err := services.Map(cloudProvider)
if err != nil {
return nil, err
}
svcConfigs, apiErr := c.serviceConfigRepo.getAllForAccount(
ctx, orgId, account.ID.StringValue(),
)
if apiErr != nil {
return nil, model.WrapApiError(
apiErr, "couldn't get service configs for cloud account",
)
}
// accumulate config in a fixed order to ensure same config generated across runs
configuredServices := maps.Keys(svcConfigs)
slices.Sort(configuredServices)
for _, svcType := range configuredServices {
definition, ok := services[svcType]
if !ok {
continue
}
config := svcConfigs[svcType]
err := AddServiceStrategy(svcType, compiledStrategy, definition.Strategy, config)
if err != nil {
return nil, err
}
}
return &AgentCheckInResponse{
AccountId: account.ID.StringValue(),
CloudAccountId: *account.AccountID,
RemovedAt: account.RemovedAt,
IntegrationConfig: agentConfig,
}, nil
}
type UpdateAccountConfigRequest struct {
Config types.AccountConfig `json:"config"`
}
func (c *Controller) UpdateAccountConfig(ctx context.Context, orgId string, cloudProvider string, accountId string, req UpdateAccountConfigRequest) (*types.Account, *model.ApiError) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
accountRecord, apiErr := c.accountsRepo.upsert(
ctx, orgId, cloudProvider, &accountId, &req.Config, nil, nil, nil,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't upsert cloud account")
}
account := accountRecord.Account()
return &account, nil
}
func (c *Controller) DisconnectAccount(ctx context.Context, orgId string, cloudProvider string, accountId string) (*types.CloudIntegration, *model.ApiError) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
account, apiErr := c.accountsRepo.get(ctx, orgId, cloudProvider, accountId)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't disconnect account")
}
tsNow := time.Now()
account, apiErr = c.accountsRepo.upsert(
ctx, orgId, cloudProvider, &accountId, nil, nil, nil, &tsNow,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't disconnect account")
}
return account, nil
}
type ListServicesResponse struct {
Services []ServiceSummary `json:"services"`
}
func (c *Controller) ListServices(
ctx context.Context,
orgID string,
cloudProvider string,
cloudAccountId *string,
) (*ListServicesResponse, *model.ApiError) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
definitions, apiErr := services.List(cloudProvider)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't list cloud services")
}
svcConfigs := map[string]*types.CloudServiceConfig{}
if cloudAccountId != nil {
activeAccount, apiErr := c.accountsRepo.getConnectedCloudAccount(
ctx, orgID, cloudProvider, *cloudAccountId,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't get active account")
}
svcConfigs, apiErr = c.serviceConfigRepo.getAllForAccount(
ctx, orgID, activeAccount.ID.StringValue(),
)
if apiErr != nil {
return nil, model.WrapApiError(
apiErr, "couldn't get service configs for cloud account",
)
}
}
summaries := []ServiceSummary{}
for _, def := range definitions {
summary := ServiceSummary{
Metadata: def.Metadata,
}
summary.Config = svcConfigs[summary.Id]
summaries = append(summaries, summary)
}
return &ListServicesResponse{
Services: summaries,
}, nil
}
func (c *Controller) GetServiceDetails(
ctx context.Context,
orgID string,
cloudProvider string,
serviceId string,
cloudAccountId *string,
) (*ServiceDetails, error) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
definition, err := services.GetServiceDefinition(cloudProvider, serviceId)
if err != nil {
return nil, err
}
details := ServiceDetails{
Definition: *definition,
}
if cloudAccountId != nil {
activeAccount, apiErr := c.accountsRepo.getConnectedCloudAccount(
ctx, orgID, cloudProvider, *cloudAccountId,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't get active account")
}
config, apiErr := c.serviceConfigRepo.get(
ctx, orgID, activeAccount.ID.StringValue(), serviceId,
)
if apiErr != nil && apiErr.Type() != model.ErrorNotFound {
return nil, model.WrapApiError(apiErr, "couldn't fetch service config")
}
if config != nil {
details.Config = config
enabled := false
if config.Metrics != nil && config.Metrics.Enabled {
enabled = true
}
// add links to service dashboards, making them clickable.
for i, d := range definition.Assets.Dashboards {
dashboardUuid := c.dashboardUuid(
cloudProvider, serviceId, d.Id,
)
if enabled {
definition.Assets.Dashboards[i].Url = fmt.Sprintf("/dashboard/%s", dashboardUuid)
} else {
definition.Assets.Dashboards[i].Url = "" // to unset the in-memory URL if enabled once and disabled afterwards
}
}
}
}
return &details, nil
}
type UpdateServiceConfigRequest struct {
CloudAccountId string `json:"cloud_account_id"`
Config types.CloudServiceConfig `json:"config"`
}
func (u *UpdateServiceConfigRequest) Validate(def *services.Definition) error {
if def.Id != services.S3Sync && u.Config.Logs != nil && u.Config.Logs.S3Buckets != nil {
return errors.NewInvalidInputf(errors.CodeInvalidInput, "s3 buckets can only be added to service-type[%s]", services.S3Sync)
} else if def.Id == services.S3Sync && u.Config.Logs != nil && u.Config.Logs.S3Buckets != nil {
for region := range u.Config.Logs.S3Buckets {
if _, found := ValidAWSRegions[region]; !found {
return errors.NewInvalidInputf(CodeInvalidCloudRegion, "invalid cloud region: %s", region)
}
}
}
return nil
}
type UpdateServiceConfigResponse struct {
Id string `json:"id"`
Config types.CloudServiceConfig `json:"config"`
}
func (c *Controller) UpdateServiceConfig(
ctx context.Context,
orgID string,
cloudProvider string,
serviceType string,
req *UpdateServiceConfigRequest,
) (*UpdateServiceConfigResponse, error) {
if apiErr := validateCloudProviderName(cloudProvider); apiErr != nil {
return nil, apiErr
}
// can only update config for a valid service.
definition, err := services.GetServiceDefinition(cloudProvider, serviceType)
if err != nil {
return nil, err
}
if err := req.Validate(definition); err != nil {
return nil, err
}
// can only update config for a connected cloud account id
_, apiErr := c.accountsRepo.getConnectedCloudAccount(
ctx, orgID, cloudProvider, req.CloudAccountId,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't find connected cloud account")
}
updatedConfig, apiErr := c.serviceConfigRepo.upsert(
ctx, orgID, cloudProvider, req.CloudAccountId, serviceType, req.Config,
)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't update service config")
}
return &UpdateServiceConfigResponse{
Id: serviceType,
Config: *updatedConfig,
}, nil
}
// All dashboards that are available based on cloud integrations configuration
// across all cloud providers
func (c *Controller) AvailableDashboards(ctx context.Context, orgId valuer.UUID) ([]*dashboardtypes.Dashboard, *model.ApiError) {
allDashboards := []*dashboardtypes.Dashboard{}
for _, provider := range []string{"aws"} {
providerDashboards, apiErr := c.AvailableDashboardsForCloudProvider(ctx, orgId, provider)
if apiErr != nil {
return nil, model.WrapApiError(
apiErr, fmt.Sprintf("couldn't get available dashboards for %s", provider),
)
}
allDashboards = append(allDashboards, providerDashboards...)
}
return allDashboards, nil
}
func (c *Controller) AvailableDashboardsForCloudProvider(ctx context.Context, orgID valuer.UUID, cloudProvider string) ([]*dashboardtypes.Dashboard, *model.ApiError) {
accountRecords, apiErr := c.accountsRepo.listConnected(ctx, orgID.StringValue(), cloudProvider)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't list connected cloud accounts")
}
// for v0, service dashboards are only available when metrics are enabled.
servicesWithAvailableMetrics := map[string]*time.Time{}
for _, ar := range accountRecords {
if ar.AccountID != nil {
configsBySvcId, apiErr := c.serviceConfigRepo.getAllForAccount(
ctx, orgID.StringValue(), ar.ID.StringValue(),
)
if apiErr != nil {
return nil, apiErr
}
for svcId, config := range configsBySvcId {
if config.Metrics != nil && config.Metrics.Enabled {
servicesWithAvailableMetrics[svcId] = &ar.CreatedAt
}
}
}
}
allServices, apiErr := services.List(cloudProvider)
if apiErr != nil {
return nil, apiErr
}
svcDashboards := []*dashboardtypes.Dashboard{}
for _, svc := range allServices {
serviceDashboardsCreatedAt := servicesWithAvailableMetrics[svc.Id]
if serviceDashboardsCreatedAt != nil {
for _, d := range svc.Assets.Dashboards {
author := fmt.Sprintf("%s-integration", cloudProvider)
svcDashboards = append(svcDashboards, &dashboardtypes.Dashboard{
ID: c.dashboardUuid(cloudProvider, svc.Id, d.Id),
Locked: true,
Data: *d.Definition,
TimeAuditable: types.TimeAuditable{
CreatedAt: *serviceDashboardsCreatedAt,
UpdatedAt: *serviceDashboardsCreatedAt,
},
UserAuditable: types.UserAuditable{
CreatedBy: author,
UpdatedBy: author,
},
OrgID: orgID,
})
}
servicesWithAvailableMetrics[svc.Id] = nil
}
}
return svcDashboards, nil
}
func (c *Controller) GetDashboardById(ctx context.Context, orgId valuer.UUID, dashboardUuid string) (*dashboardtypes.Dashboard, *model.ApiError) {
cloudProvider, _, _, apiErr := c.parseDashboardUuid(dashboardUuid)
if apiErr != nil {
return nil, apiErr
}
allDashboards, apiErr := c.AvailableDashboardsForCloudProvider(ctx, orgId, cloudProvider)
if apiErr != nil {
return nil, model.WrapApiError(apiErr, "couldn't list available dashboards")
}
for _, d := range allDashboards {
if d.ID == dashboardUuid {
return d, nil
}
}
return nil, model.NotFoundError(fmt.Errorf("couldn't find dashboard with uuid: %s", dashboardUuid))
}
func (c *Controller) dashboardUuid(
cloudProvider string, svcId string, dashboardId string,
) string {
return fmt.Sprintf("cloud-integration--%s--%s--%s", cloudProvider, svcId, dashboardId)
}
func (c *Controller) parseDashboardUuid(dashboardUuid string) (cloudProvider string, svcId string, dashboardId string, apiErr *model.ApiError) {
parts := strings.SplitN(dashboardUuid, "--", 4)
if len(parts) != 4 || parts[0] != "cloud-integration" {
return "", "", "", model.BadRequest(fmt.Errorf("invalid cloud integration dashboard id"))
}
return parts[1], parts[2], parts[3], nil
}
func (c *Controller) IsCloudIntegrationDashboardUuid(dashboardUuid string) bool {
_, _, _, apiErr := c.parseDashboardUuid(dashboardUuid)
return apiErr == nil
}

View File

@@ -1,814 +0,0 @@
package implawsprovider
import (
"context"
"fmt"
"log/slog"
"net/url"
"slices"
"sort"
"sync"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations/services"
integrationstore "github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations/store"
"github.com/SigNoz/signoz/pkg/query-service/utils"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/types/metrictypes"
qbtypes "github.com/SigNoz/signoz/pkg/types/querybuildertypes/querybuildertypesv5"
"github.com/SigNoz/signoz/pkg/types/telemetrytypes"
"github.com/SigNoz/signoz/pkg/valuer"
"golang.org/x/exp/maps"
)
var (
CodeInvalidAWSRegion = errors.MustNewCode("invalid_aws_region")
CodeDashboardNotFound = errors.MustNewCode("dashboard_not_found")
)
type awsProvider struct {
logger *slog.Logger
querier querier.Querier
accountsRepo integrationstore.CloudProviderAccountsRepository
serviceConfigRepo integrationstore.ServiceConfigDatabase
awsServiceDefinitions *services.AWSServicesProvider
}
func NewAWSCloudProvider(
logger *slog.Logger,
accountsRepo integrationstore.CloudProviderAccountsRepository,
serviceConfigRepo integrationstore.ServiceConfigDatabase,
querier querier.Querier,
) integrationtypes.CloudProvider {
awsServiceDefinitions, err := services.NewAWSCloudProviderServices()
if err != nil {
panic("failed to initialize AWS service definitions: " + err.Error())
}
return &awsProvider{
logger: logger,
querier: querier,
accountsRepo: accountsRepo,
serviceConfigRepo: serviceConfigRepo,
awsServiceDefinitions: awsServiceDefinitions,
}
}
func (a *awsProvider) GetAccountStatus(ctx context.Context, orgID, accountID string) (*integrationtypes.GettableAccountStatus, error) {
accountRecord, err := a.accountsRepo.Get(ctx, orgID, a.GetName().String(), accountID)
if err != nil {
return nil, err
}
return &integrationtypes.GettableAccountStatus{
Id: accountRecord.ID.String(),
CloudAccountId: accountRecord.AccountID,
Status: accountRecord.Status(),
}, nil
}
func (a *awsProvider) ListConnectedAccounts(ctx context.Context, orgID string) (*integrationtypes.GettableConnectedAccountsList, error) {
accountRecords, err := a.accountsRepo.ListConnected(ctx, orgID, a.GetName().String())
if err != nil {
return nil, err
}
connectedAccounts := make([]*integrationtypes.Account, 0, len(accountRecords))
for _, r := range accountRecords {
connectedAccounts = append(connectedAccounts, r.Account(a.GetName()))
}
return &integrationtypes.GettableConnectedAccountsList{
Accounts: connectedAccounts,
}, nil
}
func (a *awsProvider) AgentCheckIn(ctx context.Context, req *integrationtypes.PostableAgentCheckInPayload) (any, error) {
// agent can't check in unless the account is already created
existingAccount, err := a.accountsRepo.Get(ctx, req.OrgID, a.GetName().String(), req.ID)
if err != nil {
return nil, err
}
if existingAccount != nil && existingAccount.AccountID != nil && *existingAccount.AccountID != req.AccountID {
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "can't check in with new %s account id %s for account %s with existing %s id %s",
a.GetName().String(), req.AccountID, existingAccount.ID.StringValue(), a.GetName().String(),
*existingAccount.AccountID)
}
existingAccount, err = a.accountsRepo.GetConnectedCloudAccount(ctx, req.OrgID, a.GetName().String(), req.AccountID)
if existingAccount != nil && existingAccount.ID.StringValue() != req.ID {
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput,
"can't check in to %s account %s with id %s. already connected with id %s",
a.GetName().String(), req.AccountID, req.ID, existingAccount.ID.StringValue())
}
agentReport := integrationtypes.AgentReport{
TimestampMillis: time.Now().UnixMilli(),
Data: req.Data,
}
account, err := a.accountsRepo.Upsert(
ctx, req.OrgID, a.GetName().String(), &req.ID, nil, &req.AccountID, &agentReport, nil,
)
if err != nil {
return nil, err
}
agentConfig, err := a.getAWSAgentConfig(ctx, account)
if err != nil {
return nil, err
}
return &integrationtypes.GettableAWSAgentCheckIn{
AccountId: account.ID.StringValue(),
CloudAccountId: *account.AccountID,
RemovedAt: account.RemovedAt,
IntegrationConfig: *agentConfig,
}, nil
}
func (a *awsProvider) getAWSAgentConfig(ctx context.Context, account *integrationtypes.CloudIntegration) (*integrationtypes.AWSAgentIntegrationConfig, error) {
// prepare and return integration config to be consumed by agent
agentConfig := &integrationtypes.AWSAgentIntegrationConfig{
EnabledRegions: []string{},
TelemetryCollectionStrategy: &integrationtypes.AWSCollectionStrategy{
Metrics: &integrationtypes.AWSMetricsStrategy{},
Logs: &integrationtypes.AWSLogsStrategy{},
S3Buckets: map[string][]string{},
},
}
accountConfig := new(integrationtypes.AWSAccountConfig)
err := integrationtypes.UnmarshalJSON([]byte(account.Config), accountConfig)
if err != nil {
return nil, err
}
if accountConfig != nil && accountConfig.EnabledRegions != nil {
agentConfig.EnabledRegions = accountConfig.EnabledRegions
}
svcConfigs, err := a.serviceConfigRepo.GetAllForAccount(
ctx, account.OrgID, account.ID.StringValue(),
)
if err != nil {
return nil, err
}
// accumulate config in a fixed order to ensure same config generated across runs
configuredServices := maps.Keys(svcConfigs)
slices.Sort(configuredServices)
for _, svcType := range configuredServices {
definition, err := a.awsServiceDefinitions.GetServiceDefinition(ctx, svcType)
if err != nil {
continue
}
config := svcConfigs[svcType]
serviceConfig := new(integrationtypes.AWSCloudServiceConfig)
err = integrationtypes.UnmarshalJSON([]byte(config), serviceConfig)
if err != nil {
continue
}
if serviceConfig.Logs != nil && serviceConfig.Logs.Enabled {
if svcType == integrationtypes.S3Sync {
// S3 bucket sync; No cloudwatch logs are appended for this service type;
// Though definition is populated with a custom cloudwatch group that helps in calculating logs connection status
agentConfig.TelemetryCollectionStrategy.S3Buckets = serviceConfig.Logs.S3Buckets
} else if definition.Strategy.Logs != nil { // services that includes a logs subscription
agentConfig.TelemetryCollectionStrategy.Logs.Subscriptions = append(
agentConfig.TelemetryCollectionStrategy.Logs.Subscriptions,
definition.Strategy.Logs.Subscriptions...,
)
}
}
if serviceConfig.Metrics != nil && serviceConfig.Metrics.Enabled && definition.Strategy.Metrics != nil {
agentConfig.TelemetryCollectionStrategy.Metrics.StreamFilters = append(
agentConfig.TelemetryCollectionStrategy.Metrics.StreamFilters,
definition.Strategy.Metrics.StreamFilters...,
)
}
}
return agentConfig, nil
}
func (a *awsProvider) GetName() integrationtypes.CloudProviderType {
return integrationtypes.CloudProviderAWS
}
func (a *awsProvider) ListServices(ctx context.Context, orgID string, cloudAccountID *string) (any, error) {
svcConfigs := make(map[string]*integrationtypes.AWSCloudServiceConfig)
if cloudAccountID != nil {
activeAccount, err := a.accountsRepo.GetConnectedCloudAccount(ctx, orgID, a.GetName().String(), *cloudAccountID)
if err != nil {
return nil, err
}
serviceConfigs, err := a.serviceConfigRepo.GetAllForAccount(ctx, orgID, activeAccount.ID.String())
if err != nil {
return nil, err
}
for svcType, config := range serviceConfigs {
serviceConfig := new(integrationtypes.AWSCloudServiceConfig)
err = integrationtypes.UnmarshalJSON([]byte(config), serviceConfig)
if err != nil {
return nil, err
}
svcConfigs[svcType] = serviceConfig
}
}
summaries := make([]integrationtypes.AWSServiceSummary, 0)
definitions, err := a.awsServiceDefinitions.ListServiceDefinitions(ctx)
if err != nil {
return nil, err
}
for _, def := range definitions {
summary := integrationtypes.AWSServiceSummary{
DefinitionMetadata: def.DefinitionMetadata,
Config: nil,
}
summary.Config = svcConfigs[summary.Id]
summaries = append(summaries, summary)
}
sort.Slice(summaries, func(i, j int) bool {
return summaries[i].DefinitionMetadata.Title < summaries[j].DefinitionMetadata.Title
})
return &integrationtypes.GettableAWSServices{
Services: summaries,
}, nil
}
func (a *awsProvider) GetServiceDetails(ctx context.Context, req *integrationtypes.GetServiceDetailsReq) (any, error) {
details := new(integrationtypes.GettableAWSServiceDetails)
awsDefinition, err := a.awsServiceDefinitions.GetServiceDefinition(ctx, req.ServiceId)
if err != nil {
return nil, err
}
details.AWSDefinition = *awsDefinition
if req.CloudAccountID == nil {
return details, nil
}
config, err := a.getServiceConfig(ctx, &details.AWSDefinition, req.OrgID, a.GetName().String(), req.ServiceId, *req.CloudAccountID)
if err != nil {
return nil, err
}
if config == nil {
return details, nil
}
details.Config = config
connectionStatus, err := a.getServiceConnectionStatus(
ctx,
*req.CloudAccountID,
req.OrgID,
&details.AWSDefinition,
config,
)
if err != nil {
return nil, err
}
details.ConnectionStatus = connectionStatus
return details, nil
}
func (a *awsProvider) getServiceConnectionStatus(
ctx context.Context,
cloudAccountID string,
orgID valuer.UUID,
def *integrationtypes.AWSDefinition,
serviceConfig *integrationtypes.AWSCloudServiceConfig,
) (*integrationtypes.ServiceConnectionStatus, error) {
if def.Strategy == nil {
return nil, nil
}
resp := new(integrationtypes.ServiceConnectionStatus)
wg := sync.WaitGroup{}
if def.Strategy.Metrics != nil && serviceConfig.Metrics.Enabled {
wg.Add(1)
go func() {
defer utils.RecoverPanic(func(err interface{}, stack []byte) {
a.logger.ErrorContext(
ctx, "panic while getting service metrics connection status",
"service", def.DefinitionMetadata.Id,
"error", err,
"stack", string(stack),
)
})
defer wg.Done()
status, _ := a.getServiceMetricsConnectionStatus(ctx, cloudAccountID, orgID, def)
resp.Metrics = status
}()
}
if def.Strategy.Logs != nil && serviceConfig.Logs.Enabled {
wg.Add(1)
go func() {
defer utils.RecoverPanic(func(err interface{}, stack []byte) {
a.logger.ErrorContext(
ctx, "panic while getting service logs connection status",
"service", def.DefinitionMetadata.Id,
"error", err,
"stack", string(stack),
)
})
defer wg.Done()
status, _ := a.getServiceLogsConnectionStatus(ctx, cloudAccountID, orgID, def)
resp.Logs = status
}()
}
wg.Wait()
return resp, nil
}
func (a *awsProvider) getServiceMetricsConnectionStatus(
ctx context.Context,
cloudAccountID string,
orgID valuer.UUID,
def *integrationtypes.AWSDefinition,
) ([]*integrationtypes.SignalConnectionStatus, error) {
if def.Strategy == nil ||
len(def.Strategy.Metrics.StreamFilters) < 1 ||
len(def.DataCollected.Metrics) < 1 {
return nil, nil
}
statusResp := make([]*integrationtypes.SignalConnectionStatus, 0)
for _, metric := range def.IngestionStatusCheck.Metrics {
statusResp = append(statusResp, &integrationtypes.SignalConnectionStatus{
CategoryID: metric.Category,
CategoryDisplayName: metric.DisplayName,
})
}
for index, category := range def.IngestionStatusCheck.Metrics {
queries := make([]qbtypes.QueryEnvelope, 0)
for _, check := range category.Checks {
filterExpression := fmt.Sprintf(`cloud.provider="aws" AND cloud.account.id="%s"`, cloudAccountID)
f := ""
for _, attribute := range check.Attributes {
f = fmt.Sprintf("%s %s", attribute.Name, attribute.Operator)
if attribute.Value != "" {
f = fmt.Sprintf("%s '%s'", f, attribute.Value)
}
filterExpression = fmt.Sprintf("%s AND %s", filterExpression, f)
}
queries = append(queries, qbtypes.QueryEnvelope{
Type: qbtypes.QueryTypeBuilder,
Spec: qbtypes.QueryBuilderQuery[qbtypes.MetricAggregation]{
Name: valuer.GenerateUUID().String(),
Signal: telemetrytypes.SignalMetrics,
Aggregations: []qbtypes.MetricAggregation{{
MetricName: check.Key,
TimeAggregation: metrictypes.TimeAggregationAvg,
SpaceAggregation: metrictypes.SpaceAggregationAvg,
}},
Filter: &qbtypes.Filter{
Expression: filterExpression,
},
},
})
}
resp, err := a.querier.QueryRange(ctx, orgID, &qbtypes.QueryRangeRequest{
SchemaVersion: "v5",
Start: uint64(time.Now().Add(-time.Hour).UnixMilli()),
End: uint64(time.Now().UnixMilli()),
RequestType: qbtypes.RequestTypeScalar,
CompositeQuery: qbtypes.CompositeQuery{
Queries: queries,
},
})
if err != nil {
a.logger.DebugContext(ctx,
"error querying for service metrics connection status",
"error", err,
"service", def.DefinitionMetadata.Id,
)
continue
}
if resp != nil && len(resp.Data.Results) < 1 {
continue
}
queryResponse, ok := resp.Data.Results[0].(*qbtypes.TimeSeriesData)
if !ok {
a.logger.ErrorContext(ctx, "unexpected query response type for service metrics connection status",
"service", def.DefinitionMetadata.Id,
)
return nil, errors.NewInternalf(errors.CodeInternal, "unexpected query response type: %T", resp.Data.Results[0])
}
if queryResponse == nil ||
len(queryResponse.Aggregations) < 1 ||
len(queryResponse.Aggregations[0].Series) < 1 ||
len(queryResponse.Aggregations[0].Series[0].Values) < 1 {
continue
}
statusResp[index] = &integrationtypes.SignalConnectionStatus{
CategoryID: category.Category,
CategoryDisplayName: category.DisplayName,
LastReceivedTsMillis: queryResponse.Aggregations[0].Series[0].Values[0].Timestamp,
LastReceivedFrom: "signoz-aws-integration",
}
}
return statusResp, nil
}
func (a *awsProvider) getServiceLogsConnectionStatus(
ctx context.Context,
cloudAccountID string,
orgID valuer.UUID,
def *integrationtypes.AWSDefinition,
) ([]*integrationtypes.SignalConnectionStatus, error) {
if def.Strategy == nil ||
len(def.Strategy.Logs.Subscriptions) < 1 ||
len(def.DataCollected.Logs) < 1 {
return nil, nil
}
statusResp := make([]*integrationtypes.SignalConnectionStatus, 0)
for _, log := range def.IngestionStatusCheck.Logs {
statusResp = append(statusResp, &integrationtypes.SignalConnectionStatus{
CategoryID: log.Category,
CategoryDisplayName: log.DisplayName,
})
}
for index, category := range def.IngestionStatusCheck.Logs {
queries := make([]qbtypes.QueryEnvelope, 0)
for _, check := range category.Checks {
filterExpression := fmt.Sprintf(`cloud.account.id="%s"`, cloudAccountID)
f := ""
for _, attribute := range check.Attributes {
f = fmt.Sprintf("%s %s", attribute.Name, attribute.Operator)
if attribute.Value != "" {
f = fmt.Sprintf("%s '%s'", f, attribute.Value)
}
filterExpression = fmt.Sprintf("%s AND %s", filterExpression, f)
}
queries = append(queries, qbtypes.QueryEnvelope{
Type: qbtypes.QueryTypeBuilder,
Spec: qbtypes.QueryBuilderQuery[qbtypes.LogAggregation]{
Name: valuer.GenerateUUID().String(),
Signal: telemetrytypes.SignalLogs,
Aggregations: []qbtypes.LogAggregation{{
Expression: "count()",
}},
Filter: &qbtypes.Filter{
Expression: filterExpression,
},
Limit: 10,
Offset: 0,
},
})
}
resp, err := a.querier.QueryRange(ctx, orgID, &qbtypes.QueryRangeRequest{
SchemaVersion: "v1",
Start: uint64(time.Now().Add(-time.Hour * 1).UnixMilli()),
End: uint64(time.Now().UnixMilli()),
RequestType: qbtypes.RequestTypeTimeSeries,
CompositeQuery: qbtypes.CompositeQuery{
Queries: queries,
},
})
if err != nil {
a.logger.DebugContext(ctx,
"error querying for service logs connection status",
"error", err,
"service", def.DefinitionMetadata.Id,
)
continue
}
if resp != nil && len(resp.Data.Results) < 1 {
continue
}
queryResponse, ok := resp.Data.Results[0].(*qbtypes.TimeSeriesData)
if !ok {
a.logger.ErrorContext(ctx, "unexpected query response type for service logs connection status",
"service", def.DefinitionMetadata.Id,
)
return nil, errors.NewInternalf(errors.CodeInternal, "unexpected query response type: %T", resp.Data.Results[0])
}
if queryResponse == nil ||
len(queryResponse.Aggregations) < 1 ||
len(queryResponse.Aggregations[0].Series) < 1 ||
len(queryResponse.Aggregations[0].Series[0].Values) < 1 {
continue
}
statusResp[index] = &integrationtypes.SignalConnectionStatus{
CategoryID: category.Category,
CategoryDisplayName: category.DisplayName,
LastReceivedTsMillis: queryResponse.Aggregations[0].Series[0].Values[0].Timestamp,
LastReceivedFrom: "signoz-aws-integration",
}
}
return statusResp, nil
}
func (a *awsProvider) getServiceConfig(ctx context.Context,
def *integrationtypes.AWSDefinition, orgID valuer.UUID, cloudProvider, serviceId, cloudAccountId string,
) (*integrationtypes.AWSCloudServiceConfig, error) {
activeAccount, err := a.accountsRepo.GetConnectedCloudAccount(ctx, orgID.String(), cloudProvider, cloudAccountId)
if err != nil {
return nil, err
}
config, err := a.serviceConfigRepo.Get(ctx, orgID.String(), activeAccount.ID.StringValue(), serviceId)
if err != nil {
if errors.Ast(err, errors.TypeNotFound) {
return nil, nil
}
return nil, err
}
serviceConfig := new(integrationtypes.AWSCloudServiceConfig)
err = integrationtypes.UnmarshalJSON(config, serviceConfig)
if err != nil {
return nil, err
}
if config != nil && serviceConfig.Metrics != nil && serviceConfig.Metrics.Enabled {
def.PopulateDashboardURLs(a.GetName(), serviceId)
}
return serviceConfig, nil
}
func (a *awsProvider) GetAvailableDashboards(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error) {
accountRecords, err := a.accountsRepo.ListConnected(ctx, orgID.StringValue(), a.GetName().String())
if err != nil {
return nil, err
}
// for now service dashboards are only available when metrics are enabled.
servicesWithAvailableMetrics := map[string]*time.Time{}
for _, ar := range accountRecords {
if ar.AccountID != nil {
configsBySvcId, err := a.serviceConfigRepo.GetAllForAccount(ctx, orgID.StringValue(), ar.ID.StringValue())
if err != nil {
return nil, err
}
for svcId, config := range configsBySvcId {
serviceConfig := new(integrationtypes.AWSCloudServiceConfig)
err = integrationtypes.UnmarshalJSON(config, serviceConfig)
if err != nil {
return nil, err
}
if serviceConfig.Metrics != nil && serviceConfig.Metrics.Enabled {
servicesWithAvailableMetrics[svcId] = &ar.CreatedAt
}
}
}
}
svcDashboards := make([]*dashboardtypes.Dashboard, 0)
allServices, err := a.awsServiceDefinitions.ListServiceDefinitions(ctx)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "failed to list aws service definitions")
}
for _, svc := range allServices {
serviceDashboardsCreatedAt, ok := servicesWithAvailableMetrics[svc.Id]
if ok {
svcDashboards = append(
svcDashboards,
integrationtypes.GetDashboardsFromAssets(svc.Id, orgID, a.GetName(), serviceDashboardsCreatedAt, svc.Assets)...,
)
servicesWithAvailableMetrics[svc.Id] = nil
}
}
return svcDashboards, nil
}
func (a *awsProvider) GetDashboard(ctx context.Context, req *integrationtypes.GettableDashboard) (*dashboardtypes.Dashboard, error) {
allDashboards, err := a.GetAvailableDashboards(ctx, req.OrgID)
if err != nil {
return nil, err
}
for _, d := range allDashboards {
if d.ID == req.ID {
return d, nil
}
}
return nil, errors.NewNotFoundf(CodeDashboardNotFound, "dashboard with id %s not found", req.ID)
}
func (a *awsProvider) GenerateConnectionArtifact(ctx context.Context, req *integrationtypes.PostableConnectionArtifact) (any, error) {
connection := new(integrationtypes.PostableAWSConnectionUrl)
err := integrationtypes.UnmarshalJSON(req.Data, connection)
if err != nil {
return nil, err
}
if connection.AccountConfig != nil {
for _, region := range connection.AccountConfig.EnabledRegions {
if integrationtypes.ValidAWSRegions[region] {
continue
}
return nil, errors.NewInvalidInputf(CodeInvalidAWSRegion, "invalid aws region: %s", region)
}
}
config, err := integrationtypes.MarshalJSON(connection.AccountConfig)
if err != nil {
return nil, err
}
account, err := a.accountsRepo.Upsert(
ctx, req.OrgID, integrationtypes.CloudProviderAWS.String(), nil, config,
nil, nil, nil,
)
if err != nil {
return nil, err
}
agentVersion := "v0.0.8"
if connection.AgentConfig.Version != "" {
agentVersion = connection.AgentConfig.Version
}
baseURL := fmt.Sprintf("https://%s.console.aws.amazon.com/cloudformation/home",
connection.AgentConfig.Region)
u, _ := url.Parse(baseURL)
q := u.Query()
q.Set("region", connection.AgentConfig.Region)
u.Fragment = "/stacks/quickcreate"
u.RawQuery = q.Encode()
q = u.Query()
q.Set("stackName", "signoz-integration")
q.Set("templateURL", fmt.Sprintf("https://signoz-integrations.s3.us-east-1.amazonaws.com/aws-quickcreate-template-%s.json", agentVersion))
q.Set("param_SigNozIntegrationAgentVersion", agentVersion)
q.Set("param_SigNozApiUrl", connection.AgentConfig.SigNozAPIUrl)
q.Set("param_SigNozApiKey", connection.AgentConfig.SigNozAPIKey)
q.Set("param_SigNozAccountId", account.ID.StringValue())
q.Set("param_IngestionUrl", connection.AgentConfig.IngestionUrl)
q.Set("param_IngestionKey", connection.AgentConfig.IngestionKey)
return &integrationtypes.GettableAWSConnectionUrl{
AccountId: account.ID.StringValue(),
ConnectionUrl: u.String() + "?&" + q.Encode(), // this format is required by AWS
}, nil
}
func (a *awsProvider) UpdateServiceConfig(ctx context.Context, req *integrationtypes.PatchableServiceConfig) (any, error) {
definition, err := a.awsServiceDefinitions.GetServiceDefinition(ctx, req.ServiceId)
if err != nil {
return nil, err
}
serviceConfig := new(integrationtypes.UpdatableAWSCloudServiceConfig)
err = integrationtypes.UnmarshalJSON(req.Config, serviceConfig)
if err != nil {
return nil, err
}
if err = serviceConfig.Config.Validate(definition); err != nil {
return nil, err
}
// can only update config for a connected cloud account id
_, err = a.accountsRepo.GetConnectedCloudAccount(
ctx, req.OrgID, a.GetName().String(), serviceConfig.CloudAccountId,
)
if err != nil {
return nil, err
}
serviceConfigBytes, err := integrationtypes.MarshalJSON(serviceConfig)
if err != nil {
return nil, err
}
updatedConfig, err := a.serviceConfigRepo.Upsert(
ctx, req.OrgID, a.GetName().String(), serviceConfig.CloudAccountId, req.ServiceId, serviceConfigBytes,
)
if err != nil {
return nil, err
}
err = integrationtypes.UnmarshalJSON(updatedConfig, serviceConfig)
if err != nil {
return nil, err
}
return &integrationtypes.PatchServiceConfigResponse{
ServiceId: req.ServiceId,
Config: serviceConfig.Config,
}, nil
}
func (a *awsProvider) UpdateAccountConfig(ctx context.Context, req *integrationtypes.PatchableAccountConfig) (any, error) {
config := new(integrationtypes.PatchableAWSAccountConfig)
err := integrationtypes.UnmarshalJSON(req.Data, config)
if err != nil {
return nil, err
}
if config.Config == nil {
return nil, errors.NewInvalidInputf(errors.CodeInvalidInput, "account config can't be null")
}
for _, region := range config.Config.EnabledRegions {
if integrationtypes.ValidAWSRegions[region] {
continue
}
return nil, errors.NewInvalidInputf(CodeInvalidAWSRegion, "invalid aws region: %s", region)
}
configBytes, err := integrationtypes.MarshalJSON(config.Config)
if err != nil {
return nil, err
}
// account must exist to update config, but it doesn't need to be connected
_, err = a.accountsRepo.Get(ctx, req.OrgID, a.GetName().String(), req.AccountId)
if err != nil {
return nil, err
}
accountRecord, err := a.accountsRepo.Upsert(
ctx, req.OrgID, a.GetName().String(), &req.AccountId, configBytes, nil, nil, nil,
)
if err != nil {
return nil, err
}
return accountRecord.Account(a.GetName()), nil
}
func (a *awsProvider) DisconnectAccount(ctx context.Context, orgID, accountID string) (*integrationtypes.CloudIntegration, error) {
account, err := a.accountsRepo.Get(ctx, orgID, a.GetName().String(), accountID)
if err != nil {
return nil, err
}
tsNow := time.Now()
account, err = a.accountsRepo.Upsert(
ctx, orgID, a.GetName().String(), &accountID, nil, nil, nil, &tsNow,
)
if err != nil {
return nil, err
}
return account, nil
}

View File

@@ -1 +1,94 @@
package cloudintegrations
import (
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations/services"
"github.com/SigNoz/signoz/pkg/types"
)
type ServiceSummary struct {
services.Metadata
Config *types.CloudServiceConfig `json:"config"`
}
type ServiceDetails struct {
services.Definition
Config *types.CloudServiceConfig `json:"config"`
ConnectionStatus *ServiceConnectionStatus `json:"status,omitempty"`
}
type AccountStatus struct {
Integration AccountIntegrationStatus `json:"integration"`
}
type AccountIntegrationStatus struct {
LastHeartbeatTsMillis *int64 `json:"last_heartbeat_ts_ms"`
}
type LogsConfig struct {
Enabled bool `json:"enabled"`
S3Buckets map[string][]string `json:"s3_buckets,omitempty"`
}
type MetricsConfig struct {
Enabled bool `json:"enabled"`
}
type ServiceConnectionStatus struct {
Logs *SignalConnectionStatus `json:"logs"`
Metrics *SignalConnectionStatus `json:"metrics"`
}
type SignalConnectionStatus struct {
LastReceivedTsMillis int64 `json:"last_received_ts_ms"` // epoch milliseconds
LastReceivedFrom string `json:"last_received_from"` // resource identifier
}
type CompiledCollectionStrategy = services.CollectionStrategy
func NewCompiledCollectionStrategy(provider string) (*CompiledCollectionStrategy, error) {
if provider == "aws" {
return &CompiledCollectionStrategy{
Provider: "aws",
AWSMetrics: &services.AWSMetricsStrategy{},
AWSLogs: &services.AWSLogsStrategy{},
}, nil
}
return nil, errors.NewNotFoundf(services.CodeUnsupportedCloudProvider, "unsupported cloud provider: %s", provider)
}
// Helper for accumulating strategies for enabled services.
func AddServiceStrategy(serviceType string, cs *CompiledCollectionStrategy,
definitionStrat *services.CollectionStrategy, config *types.CloudServiceConfig) error {
if definitionStrat.Provider != cs.Provider {
return errors.NewInternalf(CodeMismatchCloudProvider, "can't add %s service strategy to compiled strategy for %s",
definitionStrat.Provider, cs.Provider)
}
if cs.Provider == "aws" {
if config.Logs != nil && config.Logs.Enabled {
if serviceType == services.S3Sync {
// S3 bucket sync; No cloudwatch logs are appended for this service type;
// Though definition is populated with a custom cloudwatch group that helps in calculating logs connection status
cs.S3Buckets = config.Logs.S3Buckets
} else if definitionStrat.AWSLogs != nil { // services that includes a logs subscription
cs.AWSLogs.Subscriptions = append(
cs.AWSLogs.Subscriptions,
definitionStrat.AWSLogs.Subscriptions...,
)
}
}
if config.Metrics != nil && config.Metrics.Enabled && definitionStrat.AWSMetrics != nil {
cs.AWSMetrics.StreamFilters = append(
cs.AWSMetrics.StreamFilters,
definitionStrat.AWSMetrics.StreamFilters...,
)
}
return nil
}
return errors.NewNotFoundf(services.CodeUnsupportedCloudProvider, "unsupported cloud provider: %s", cs.Provider)
}

View File

@@ -1,27 +0,0 @@
package cloudintegrations
import (
"log/slog"
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations/implawsprovider"
integrationstore "github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations/store"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
)
func NewCloudProviderRegistry(
logger *slog.Logger,
store sqlstore.SQLStore,
querier querier.Querier,
) map[integrationtypes.CloudProviderType]integrationtypes.CloudProvider {
registry := make(map[integrationtypes.CloudProviderType]integrationtypes.CloudProvider)
accountsRepo := integrationstore.NewCloudProviderAccountsRepository(store)
serviceConfigRepo := integrationstore.NewServiceConfigRepository(store)
awsProviderImpl := implawsprovider.NewAWSCloudProvider(logger, accountsRepo, serviceConfigRepo, querier)
registry[integrationtypes.CloudProviderAWS] = awsProviderImpl
return registry
}

View File

@@ -1,63 +1,64 @@
package store
package cloudintegrations
import (
"context"
"database/sql"
"fmt"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
var (
CodeServiceConfigNotFound = errors.MustNewCode("service_config_not_found")
)
type ServiceConfigDatabase interface {
Get(
get(
ctx context.Context,
orgID string,
cloudAccountId string,
serviceType string,
) ([]byte, error)
) (*types.CloudServiceConfig, *model.ApiError)
Upsert(
upsert(
ctx context.Context,
orgID string,
cloudProvider string,
cloudAccountId string,
serviceId string,
config []byte,
) ([]byte, error)
config types.CloudServiceConfig,
) (*types.CloudServiceConfig, *model.ApiError)
GetAllForAccount(
getAllForAccount(
ctx context.Context,
orgID string,
cloudAccountId string,
) (
map[string][]byte,
error,
configsBySvcId map[string]*types.CloudServiceConfig,
apiErr *model.ApiError,
)
}
func NewServiceConfigRepository(store sqlstore.SQLStore) ServiceConfigDatabase {
return &serviceConfigSQLRepository{store: store}
func newServiceConfigRepository(store sqlstore.SQLStore) (
*serviceConfigSQLRepository, error,
) {
return &serviceConfigSQLRepository{
store: store,
}, nil
}
type serviceConfigSQLRepository struct {
store sqlstore.SQLStore
}
func (r *serviceConfigSQLRepository) Get(
func (r *serviceConfigSQLRepository) get(
ctx context.Context,
orgID string,
cloudAccountId string,
serviceType string,
) ([]byte, error) {
var result integrationtypes.CloudIntegrationService
) (*types.CloudServiceConfig, *model.ApiError) {
var result types.CloudIntegrationService
err := r.store.BunDB().NewSelect().
Model(&result).
@@ -66,30 +67,36 @@ func (r *serviceConfigSQLRepository) Get(
Where("ci.id = ?", cloudAccountId).
Where("cis.type = ?", serviceType).
Scan(ctx)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, errors.WrapNotFoundf(err, CodeServiceConfigNotFound, "couldn't find config for cloud account %s", cloudAccountId)
}
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't query cloud service config")
if err == sql.ErrNoRows {
return nil, model.NotFoundError(fmt.Errorf(
"couldn't find config for cloud account %s",
cloudAccountId,
))
} else if err != nil {
return nil, model.InternalError(fmt.Errorf(
"couldn't query cloud service config: %w", err,
))
}
return []byte(result.Config), nil
return &result.Config, nil
}
func (r *serviceConfigSQLRepository) Upsert(
func (r *serviceConfigSQLRepository) upsert(
ctx context.Context,
orgID string,
cloudProvider string,
cloudAccountId string,
serviceId string,
config []byte,
) ([]byte, error) {
config types.CloudServiceConfig,
) (*types.CloudServiceConfig, *model.ApiError) {
// get cloud integration id from account id
// if the account is not connected, we don't need to upsert the config
var cloudIntegrationId string
err := r.store.BunDB().NewSelect().
Model((*integrationtypes.CloudIntegration)(nil)).
Model((*types.CloudIntegration)(nil)).
Column("id").
Where("provider = ?", cloudProvider).
Where("account_id = ?", cloudAccountId).
@@ -97,24 +104,20 @@ func (r *serviceConfigSQLRepository) Upsert(
Where("removed_at is NULL").
Where("last_agent_report is not NULL").
Scan(ctx, &cloudIntegrationId)
if err != nil {
if errors.Is(err, sql.ErrNoRows) {
return nil, errors.WrapNotFoundf(
err,
CodeCloudIntegrationAccountNotFound,
"couldn't find active cloud integration account",
)
}
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't query cloud integration id")
return nil, model.InternalError(fmt.Errorf(
"couldn't query cloud integration id: %w", err,
))
}
serviceConfig := integrationtypes.CloudIntegrationService{
serviceConfig := types.CloudIntegrationService{
Identifiable: types.Identifiable{ID: valuer.GenerateUUID()},
TimeAuditable: types.TimeAuditable{
CreatedAt: time.Now(),
UpdatedAt: time.Now(),
},
Config: string(config),
Config: config,
Type: serviceId,
CloudIntegrationID: cloudIntegrationId,
}
@@ -123,18 +126,21 @@ func (r *serviceConfigSQLRepository) Upsert(
On("conflict(cloud_integration_id, type) do update set config=excluded.config, updated_at=excluded.updated_at").
Exec(ctx)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't upsert cloud service config")
return nil, model.InternalError(fmt.Errorf(
"could not upsert cloud service config: %w", err,
))
}
return config, nil
return &serviceConfig.Config, nil
}
func (r *serviceConfigSQLRepository) GetAllForAccount(
func (r *serviceConfigSQLRepository) getAllForAccount(
ctx context.Context,
orgID string,
cloudAccountId string,
) (map[string][]byte, error) {
var serviceConfigs []integrationtypes.CloudIntegrationService
) (map[string]*types.CloudServiceConfig, *model.ApiError) {
serviceConfigs := []types.CloudIntegrationService{}
err := r.store.BunDB().NewSelect().
Model(&serviceConfigs).
@@ -143,13 +149,15 @@ func (r *serviceConfigSQLRepository) GetAllForAccount(
Where("ci.org_id = ?", orgID).
Scan(ctx)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't query service configs from db")
return nil, model.InternalError(fmt.Errorf(
"could not query service configs from db: %w", err,
))
}
result := make(map[string][]byte)
result := map[string]*types.CloudServiceConfig{}
for _, r := range serviceConfigs {
result[r.Type] = []byte(r.Config)
result[r.Type] = &r.Config
}
return result, nil

View File

@@ -7,24 +7,6 @@
"metrics": true,
"logs": false
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_ApplicationELB_ConsumedLCUs_count",
"attributes": []
},
{
"key": "aws_ApplicationELB_ProcessedBytes_sum",
"attributes": []
}
]
}
]
},
"data_collected": {
"metrics": [
{

View File

@@ -7,75 +7,6 @@
"metrics": true,
"logs": true
},
"ingestion_status_check": {
"metrics": [
{
"category": "rest_api",
"display_name": "REST API Metrics",
"checks": [
{
"key": "aws_ApiGateway_Count_count",
"attributes": [
{
"name": "ApiName",
"operator": "EXISTS",
"value": ""
}
]
}
]
},
{
"category": "http_api",
"display_name": "HTTP API Metrics",
"checks": [
{
"key": "aws_ApiGateway_Count_count",
"attributes": [
{
"name": "ApiId",
"operator": "EXISTS",
"value": ""
}
]
}
]
},
{
"category": "websocket_api",
"display_name": "Websocket API Metrics",
"checks": [
{
"key": "aws_ApiGateway_Count_count",
"attributes": [
{
"name": "ApiId",
"operator": "EXISTS",
"value": ""
}
]
}
]
}
],
"logs": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"attributes": [
{
"name": "aws.cloudwatch.log_group_name",
"operator": "ILIKE",
"value": "API-Gateway%"
}
]
}
]
}
]
},
"data_collected": {
"metrics": [
{
@@ -217,146 +148,6 @@
"name": "aws_ApiGateway_Latency_sum",
"unit": "Milliseconds",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_4xx_sum",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_4xx_max",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_4xx_min",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_4xx_count",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_5xx_sum",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_5xx_max",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_5xx_min",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_5xx_count",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_DataProcessed_sum",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_DataProcessed_max",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_DataProcessed_min",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_DataProcessed_count",
"unit": "Bytes",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ExecutionError_sum",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ExecutionError_max",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ExecutionError_min",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ExecutionError_count",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ClientError_sum",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ClientError_max",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ClientError_min",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ClientError_count",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_IntegrationError_sum",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_IntegrationError_max",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_IntegrationError_min",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_IntegrationError_count",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ConnectCount_sum",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ConnectCount_max",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ConnectCount_min",
"unit": "Count",
"type": "Gauge"
},
{
"name": "aws_ApiGateway_ConnectCount_count",
"unit": "Count",
"type": "Gauge"
}
],
"logs": [

View File

@@ -7,24 +7,6 @@
"metrics": true,
"logs": false
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_DynamoDB_AccountMaxReads_max",
"attributes": []
},
{
"key": "aws_DynamoDB_AccountProvisionedReadCapacityUtilization_max",
"attributes": []
}
]
}
]
},
"data_collected": {
"metrics": [
{
@@ -409,4 +391,4 @@
}
]
}
}
}

View File

@@ -7,24 +7,6 @@
"metrics": true,
"logs": false
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_EC2_CPUUtilization_max",
"attributes": []
},
{
"key": "aws_EC2_NetworkIn_max",
"attributes": []
}
]
}
]
},
"data_collected": {
"metrics": [
{
@@ -533,4 +515,4 @@
}
]
}
}
}

View File

@@ -7,81 +7,6 @@
"metrics": true,
"logs": true
},
"ingestion_status_check": {
"metrics": [
{
"category": "overview",
"display_name": "Overview",
"checks": [
{
"key": "aws_ECS_CPUUtilization_max",
"attributes": []
},
{
"key": "aws_ECS_MemoryUtilization_max",
"attributes": []
}
]
},
{
"category": "containerinsights",
"display_name": "Container Insights",
"checks": [
{
"key": "aws_ECS_ContainerInsights_NetworkRxBytes_max",
"attributes": []
},
{
"key": "aws_ECS_ContainerInsights_StorageReadBytes_max",
"attributes": []
}
]
},
{
"category": "enhanced_containerinsights",
"display_name": "Enhanced Container Insights",
"checks": [
{
"key": "aws_ECS_ContainerInsights_ContainerCpuUtilization_max",
"attributes": [
{
"name": "TaskId",
"operator": "EXISTS",
"value": ""
}
]
},
{
"key": "aws_ECS_ContainerInsights_TaskMemoryUtilization_max",
"attributes": [
{
"name": "TaskId",
"operator": "EXISTS",
"value": ""
}
]
}
]
}
],
"logs": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"attributes": [
{
"name": "aws.cloudwatch.log_group_name",
"operator": "ILIKE",
"value": "%/ecs/%"
}
]
}
]
}
]
},
"data_collected": {
"metrics": [
{

View File

@@ -7,20 +7,6 @@
"metrics": true,
"logs": false
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_ElastiCache_CacheHitRate_max",
"attributes": []
}
]
}
]
},
"data_collected": {
"metrics":[
{
@@ -1942,7 +1928,7 @@
"unit": "Percent",
"type": "Gauge",
"description": ""
}
}
]
},
"telemetry_collection_strategy": {
@@ -1965,4 +1951,4 @@
}
]
}
}
}

View File

@@ -7,37 +7,6 @@
"metrics": true,
"logs": true
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_Lambda_Invocations_sum",
"attributes": []
}
]
}
],
"logs": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"attributes": [
{
"name": "aws.cloudwatch.log_group_name",
"operator": "ILIKE",
"value": "/aws/lambda%"
}
]
}
]
}
]
},
"data_collected": {
"metrics": [
{

View File

@@ -7,20 +7,6 @@
"metrics": true,
"logs": false
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_Kafka_KafkaDataLogsDiskUsed_max",
"attributes": []
}
]
}
]
},
"data_collected": {
"metrics": [
{
@@ -1102,3 +1088,4 @@
]
}
}

View File

@@ -7,37 +7,6 @@
"metrics": true,
"logs": true
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_RDS_CPUUtilization_max",
"attributes": []
}
]
}
],
"logs": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"attributes": [
{
"name": "resources.aws.cloudwatch.log_group_name",
"operator": "ILIKE",
"value": "/aws/rds%"
}
]
}
]
}
]
},
"data_collected": {
"metrics": [
{
@@ -831,4 +800,4 @@
}
]
}
}
}

View File

@@ -7,20 +7,6 @@
"metrics": true,
"logs": false
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_SNS_NumberOfMessagesPublished_sum",
"attributes": []
}
]
}
]
},
"data_collected": {
"metrics": [
{
@@ -141,4 +127,4 @@
}
]
}
}
}

View File

@@ -7,24 +7,6 @@
"metrics": true,
"logs": false
},
"ingestion_status_check": {
"metrics": [
{
"category": "$default",
"display_name": "Default",
"checks": [
{
"key": "aws_SQS_SentMessageSize_max",
"attributes": []
},
{
"key": "aws_SQS_NumberOfMessagesSent_sum",
"attributes": []
}
]
}
]
},
"data_collected": {
"metrics": [
{
@@ -265,4 +247,4 @@
}
]
}
}
}

View File

@@ -0,0 +1,91 @@
package services
import (
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
)
type Metadata struct {
Id string `json:"id"`
Title string `json:"title"`
Icon string `json:"icon"`
}
type Definition struct {
Metadata
Overview string `json:"overview"` // markdown
Assets Assets `json:"assets"`
SupportedSignals SupportedSignals `json:"supported_signals"`
DataCollected DataCollected `json:"data_collected"`
Strategy *CollectionStrategy `json:"telemetry_collection_strategy"`
}
type Assets struct {
Dashboards []Dashboard `json:"dashboards"`
}
type SupportedSignals struct {
Logs bool `json:"logs"`
Metrics bool `json:"metrics"`
}
type DataCollected struct {
Logs []CollectedLogAttribute `json:"logs"`
Metrics []CollectedMetric `json:"metrics"`
}
type CollectedLogAttribute struct {
Name string `json:"name"`
Path string `json:"path"`
Type string `json:"type"`
}
type CollectedMetric struct {
Name string `json:"name"`
Type string `json:"type"`
Unit string `json:"unit"`
Description string `json:"description"`
}
type CollectionStrategy struct {
Provider string `json:"provider"`
AWSMetrics *AWSMetricsStrategy `json:"aws_metrics,omitempty"`
AWSLogs *AWSLogsStrategy `json:"aws_logs,omitempty"`
S3Buckets map[string][]string `json:"s3_buckets,omitempty"` // Only available in S3 Sync Service Type
}
type AWSMetricsStrategy struct {
// to be used as https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudwatch-metricstream.html#cfn-cloudwatch-metricstream-includefilters
StreamFilters []struct {
// json tags here are in the shape expected by AWS API as detailed at
// https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudwatch-metricstream-metricstreamfilter.html
Namespace string `json:"Namespace"`
MetricNames []string `json:"MetricNames,omitempty"`
} `json:"cloudwatch_metric_stream_filters"`
}
type AWSLogsStrategy struct {
Subscriptions []struct {
// subscribe to all logs groups with specified prefix.
// eg: `/aws/rds/`
LogGroupNamePrefix string `json:"log_group_name_prefix"`
// https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html
// "" implies no filtering is required.
FilterPattern string `json:"filter_pattern"`
} `json:"cloudwatch_logs_subscriptions"`
}
type Dashboard struct {
Id string `json:"id"`
Url string `json:"url"`
Title string `json:"title"`
Description string `json:"description"`
Image string `json:"image"`
Definition *dashboardtypes.StorableDashboardData `json:"definition,omitempty"`
}

View File

@@ -2,90 +2,128 @@ package services
import (
"bytes"
"context"
"embed"
"encoding/json"
"fmt"
"io/fs"
"path"
"sort"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/SigNoz/signoz/pkg/query-service/model"
koanfJson "github.com/knadh/koanf/parsers/json"
"golang.org/x/exp/maps"
)
const (
S3Sync = "s3sync"
)
var (
CodeServiceDefinitionNotFound = errors.MustNewCode("service_definition_not_dound")
CodeUnsupportedCloudProvider = errors.MustNewCode("unsupported_cloud_provider")
CodeUnsupportedServiceType = errors.MustNewCode("unsupported_service_type")
)
type (
AWSServicesProvider struct {
definitions map[string]*integrationtypes.AWSDefinition
func List(cloudProvider string) ([]Definition, *model.ApiError) {
cloudServices, found := supportedServices[cloudProvider]
if !found || cloudServices == nil {
return nil, model.NotFoundError(fmt.Errorf(
"unsupported cloud provider: %s", cloudProvider,
))
}
)
func (a *AWSServicesProvider) ListServiceDefinitions(ctx context.Context) (map[string]*integrationtypes.AWSDefinition, error) {
return a.definitions, nil
services := maps.Values(cloudServices)
sort.Slice(services, func(i, j int) bool {
return services[i].Id < services[j].Id
})
return services, nil
}
func (a *AWSServicesProvider) GetServiceDefinition(ctx context.Context, serviceName string) (*integrationtypes.AWSDefinition, error) {
def, ok := a.definitions[serviceName]
if !ok {
return nil, errors.NewNotFoundf(CodeServiceDefinitionNotFound, "aws service definition not found: %s", serviceName)
}
return def, nil
}
func NewAWSCloudProviderServices() (*AWSServicesProvider, error) {
definitions, err := readAllServiceDefinitions(integrationtypes.CloudProviderAWS)
if err != nil {
return nil, err
}
serviceDefinitions := make(map[string]*integrationtypes.AWSDefinition)
for id, def := range definitions {
typedDef, ok := def.(*integrationtypes.AWSDefinition)
if !ok {
return nil, fmt.Errorf("invalid type for AWS service definition %s", id)
}
serviceDefinitions[id] = typedDef
}
return &AWSServicesProvider{
definitions: serviceDefinitions,
}, nil
}
//go:embed definitions/*
var definitionFiles embed.FS
func readAllServiceDefinitions(cloudProvider valuer.String) (map[string]any, error) {
rootDirName := "definitions"
cloudProviderDirPath := path.Join(rootDirName, cloudProvider.String())
cloudServices, err := readServiceDefinitionsFromDir(cloudProvider, cloudProviderDirPath)
if err != nil {
return nil, err
}
if len(cloudServices) < 1 {
return nil, errors.NewInternalf(errors.CodeInternal, "no service definitions found in %s", cloudProviderDirPath)
func Map(cloudProvider string) (map[string]Definition, error) {
cloudServices, found := supportedServices[cloudProvider]
if !found || cloudServices == nil {
return nil, errors.Newf(errors.TypeNotFound, CodeUnsupportedCloudProvider, "unsupported cloud provider: %s", cloudProvider)
}
return cloudServices, nil
}
func readServiceDefinitionsFromDir(cloudProvider valuer.String, cloudProviderDirPath string) (map[string]any, error) {
svcDefDirs, err := fs.ReadDir(definitionFiles, cloudProviderDirPath)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't list integrations dirs")
func GetServiceDefinition(cloudProvider, serviceType string) (*Definition, error) {
cloudServices := supportedServices[cloudProvider]
if cloudServices == nil {
return nil, errors.Newf(errors.TypeNotFound, CodeUnsupportedCloudProvider, "unsupported cloud provider: %s", cloudProvider)
}
svcDefs := make(map[string]any)
svc, exists := cloudServices[serviceType]
if !exists {
return nil, errors.Newf(errors.TypeNotFound, CodeUnsupportedServiceType, "%s service not found: %s", cloudProvider, serviceType)
}
return &svc, nil
}
// End of API. Logic for reading service definition files follows
// Service details read from ./serviceDefinitions
// { "providerName": { "service_id": {...}} }
var supportedServices map[string]map[string]Definition
func init() {
err := readAllServiceDefinitions()
if err != nil {
panic(fmt.Errorf(
"couldn't read cloud service definitions: %w", err,
))
}
}
//go:embed definitions/*
var definitionFiles embed.FS
func readAllServiceDefinitions() error {
supportedServices = map[string]map[string]Definition{}
rootDirName := "definitions"
cloudProviderDirs, err := fs.ReadDir(definitionFiles, rootDirName)
if err != nil {
return fmt.Errorf("couldn't read dirs in %s: %w", rootDirName, err)
}
for _, d := range cloudProviderDirs {
if !d.IsDir() {
continue
}
cloudProvider := d.Name()
cloudProviderDirPath := path.Join(rootDirName, cloudProvider)
cloudServices, err := readServiceDefinitionsFromDir(cloudProvider, cloudProviderDirPath)
if err != nil {
return fmt.Errorf("couldn't read %s service definitions: %w", cloudProvider, err)
}
if len(cloudServices) < 1 {
return fmt.Errorf("no %s services could be read", cloudProvider)
}
supportedServices[cloudProvider] = cloudServices
}
return nil
}
func readServiceDefinitionsFromDir(cloudProvider string, cloudProviderDirPath string) (
map[string]Definition, error,
) {
svcDefDirs, err := fs.ReadDir(definitionFiles, cloudProviderDirPath)
if err != nil {
return nil, fmt.Errorf("couldn't list integrations dirs: %w", err)
}
svcDefs := map[string]Definition{}
for _, d := range svcDefDirs {
if !d.IsDir() {
@@ -95,71 +133,103 @@ func readServiceDefinitionsFromDir(cloudProvider valuer.String, cloudProviderDir
svcDirPath := path.Join(cloudProviderDirPath, d.Name())
s, err := readServiceDefinition(cloudProvider, svcDirPath)
if err != nil {
return nil, err
return nil, fmt.Errorf("couldn't read svc definition for %s: %w", d.Name(), err)
}
_, exists := svcDefs[s.GetId()]
_, exists := svcDefs[s.Id]
if exists {
return nil, errors.NewInternalf(errors.CodeInternal, "duplicate service definition for id %s at %s", s.GetId(), d.Name())
return nil, fmt.Errorf(
"duplicate service definition for id %s at %s", s.Id, d.Name(),
)
}
svcDefs[s.GetId()] = s
svcDefs[s.Id] = *s
}
return svcDefs, nil
}
func readServiceDefinition(cloudProvider valuer.String, svcDirpath string) (integrationtypes.Definition, error) {
func readServiceDefinition(cloudProvider string, svcDirpath string) (*Definition, error) {
integrationJsonPath := path.Join(svcDirpath, "integration.json")
serializedSpec, err := definitionFiles.ReadFile(integrationJsonPath)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't read integration definition in %s", svcDirpath)
return nil, fmt.Errorf(
"couldn't find integration.json in %s: %w",
svcDirpath, err,
)
}
integrationSpec, err := koanfJson.Parser().Unmarshal(serializedSpec)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't parse integration definition in %s", svcDirpath)
return nil, fmt.Errorf(
"couldn't parse integration.json from %s: %w",
integrationJsonPath, err,
)
}
hydrated, err := integrations.HydrateFileUris(integrationSpec, definitionFiles, svcDirpath)
hydrated, err := integrations.HydrateFileUris(
integrationSpec, definitionFiles, svcDirpath,
)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't hydrate integration definition in %s", svcDirpath)
return nil, fmt.Errorf(
"couldn't hydrate files referenced in service definition %s: %w",
integrationJsonPath, err,
)
}
hydratedSpec := hydrated.(map[string]any)
var serviceDef integrationtypes.Definition
switch cloudProvider {
case integrationtypes.CloudProviderAWS:
serviceDef = &integrationtypes.AWSDefinition{}
default:
// ideally this shouldn't happen hence throwing internal error
return nil, errors.NewInternalf(errors.CodeInternal, "unsupported cloud provider: %s", cloudProvider)
serviceDef, err := ParseStructWithJsonTagsFromMap[Definition](hydratedSpec)
if err != nil {
return nil, fmt.Errorf(
"couldn't parse hydrated JSON spec read from %s: %w",
integrationJsonPath, err,
)
}
err = parseStructWithJsonTagsFromMap(hydratedSpec, serviceDef)
err = validateServiceDefinition(serviceDef)
if err != nil {
return nil, err
}
err = serviceDef.Validate()
if err != nil {
return nil, err
return nil, fmt.Errorf("invalid service definition %s: %w", serviceDef.Id, err)
}
serviceDef.Strategy.Provider = cloudProvider
return serviceDef, nil
}
func parseStructWithJsonTagsFromMap(data map[string]any, target interface{}) error {
mapJson, err := json.Marshal(data)
if err != nil {
return errors.WrapInternalf(err, errors.CodeInternal, "couldn't marshal service definition json data")
func validateServiceDefinition(s *Definition) error {
// Validate dashboard data
seenDashboardIds := map[string]interface{}{}
for _, dd := range s.Assets.Dashboards {
if _, seen := seenDashboardIds[dd.Id]; seen {
return fmt.Errorf("multiple dashboards found with id %s", dd.Id)
}
seenDashboardIds[dd.Id] = nil
}
decoder := json.NewDecoder(bytes.NewReader(mapJson))
decoder.DisallowUnknownFields()
err = decoder.Decode(target)
if err != nil {
return errors.WrapInternalf(err, errors.CodeInternal, "couldn't unmarshal service definition json data")
if s.Strategy == nil {
return fmt.Errorf("telemetry_collection_strategy is required")
}
// potentially more to follow
return nil
}
func ParseStructWithJsonTagsFromMap[StructType any](data map[string]any) (
*StructType, error,
) {
mapJson, err := json.Marshal(data)
if err != nil {
return nil, fmt.Errorf("couldn't marshal map to json: %w", err)
}
var res StructType
decoder := json.NewDecoder(bytes.NewReader(mapJson))
decoder.DisallowUnknownFields()
err = decoder.Decode(&res)
if err != nil {
return nil, fmt.Errorf("couldn't unmarshal json back to struct: %w", err)
}
return &res, nil
}

View File

@@ -1,3 +1,35 @@
package services
// TODO: add more tests for services package
import (
"testing"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/stretchr/testify/require"
)
func TestAvailableServices(t *testing.T) {
require := require.New(t)
// should be able to list available services.
_, apiErr := List("bad-cloud-provider")
require.NotNil(apiErr)
require.Equal(model.ErrorNotFound, apiErr.Type())
awsSvcs, apiErr := List("aws")
require.Nil(apiErr)
require.Greater(len(awsSvcs), 0)
// should be able to get details of a service
_, err := GetServiceDefinition(
"aws", "bad-service-id",
)
require.NotNil(err)
require.True(errors.Ast(err, errors.TypeNotFound))
svc, err := GetServiceDefinition(
"aws", awsSvcs[0].Id,
)
require.Nil(err)
require.Equal(*svc, awsSvcs[0])
}

View File

@@ -6,7 +6,11 @@ import (
"database/sql"
"encoding/json"
"fmt"
"log/slog"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/flagger"
"github.com/SigNoz/signoz/pkg/modules/thirdpartyapi"
"github.com/SigNoz/signoz/pkg/queryparser"
"io"
"math"
@@ -21,19 +25,14 @@ import (
"time"
"github.com/SigNoz/signoz/pkg/alertmanager"
"github.com/SigNoz/signoz/pkg/errors"
errorsV2 "github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/flagger"
"github.com/SigNoz/signoz/pkg/http/middleware"
"github.com/SigNoz/signoz/pkg/http/render"
"github.com/SigNoz/signoz/pkg/licensing"
"github.com/SigNoz/signoz/pkg/modules/thirdpartyapi"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations/services"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/query-service/app/metricsexplorer"
"github.com/SigNoz/signoz/pkg/queryparser"
"github.com/SigNoz/signoz/pkg/signoz"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/prometheus/prometheus/promql"
@@ -45,6 +44,7 @@ import (
"github.com/SigNoz/signoz/pkg/contextlinks"
traceFunnelsModule "github.com/SigNoz/signoz/pkg/modules/tracefunnel"
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/inframetrics"
queues2 "github.com/SigNoz/signoz/pkg/query-service/app/integrations/messagingQueues/queues"
"github.com/SigNoz/signoz/pkg/query-service/app/logs"
@@ -111,7 +111,7 @@ type APIHandler struct {
IntegrationsController *integrations.Controller
cloudIntegrationsRegistry map[integrationtypes.CloudProviderType]integrationtypes.CloudProvider
CloudIntegrationsController *cloudintegrations.Controller
LogsParsingPipelineController *logparsingpipeline.LogParsingPipelineController
@@ -158,6 +158,9 @@ type APIHandlerOpts struct {
// Integrations
IntegrationsController *integrations.Controller
// Cloud Provider Integrations
CloudIntegrationsController *cloudintegrations.Controller
// Log parsing pipelines
LogsParsingPipelineController *logparsingpipeline.LogParsingPipelineController
@@ -171,8 +174,6 @@ type APIHandlerOpts struct {
QueryParserAPI *queryparser.API
Signoz *signoz.SigNoz
Logger *slog.Logger
}
// NewAPIHandler returns an APIHandler
@@ -208,18 +209,12 @@ func NewAPIHandler(opts APIHandlerOpts, config signoz.Config) (*APIHandler, erro
summaryService := metricsexplorer.NewSummaryService(opts.Reader, opts.RuleManager, opts.Signoz.Modules.Dashboard)
//quickFilterModule := quickfilter.NewAPI(opts.QuickFilterModule)
cloudIntegrationsRegistry := cloudintegrations.NewCloudProviderRegistry(
opts.Logger,
opts.Signoz.SQLStore,
opts.Signoz.Querier,
)
aH := &APIHandler{
reader: opts.Reader,
temporalityMap: make(map[string]map[v3.Temporality]bool),
ruleManager: opts.RuleManager,
IntegrationsController: opts.IntegrationsController,
cloudIntegrationsRegistry: cloudIntegrationsRegistry,
CloudIntegrationsController: opts.CloudIntegrationsController,
LogsParsingPipelineController: opts.LogsParsingPipelineController,
querier: querier,
querierV2: querierv2,
@@ -1214,22 +1209,13 @@ func (aH *APIHandler) Get(rw http.ResponseWriter, r *http.Request) {
}
dashboard := new(dashboardtypes.Dashboard)
if integrationtypes.IsCloudIntegrationDashboardUuid(id) {
cloudProvider, err := integrationtypes.GetCloudProviderFromDashboardID(id)
if err != nil {
render.Error(rw, err)
if aH.CloudIntegrationsController.IsCloudIntegrationDashboardUuid(id) {
cloudIntegrationDashboard, apiErr := aH.CloudIntegrationsController.GetDashboardById(ctx, orgID, id)
if apiErr != nil {
render.Error(rw, errorsV2.Wrapf(apiErr, errorsV2.TypeInternal, errorsV2.CodeInternal, "failed to get dashboard"))
return
}
integrationDashboard, err := aH.cloudIntegrationsRegistry[cloudProvider].GetDashboard(ctx, &integrationtypes.GettableDashboard{
ID: id,
OrgID: orgID,
})
if err != nil {
render.Error(rw, err)
return
}
dashboard = integrationDashboard
dashboard = cloudIntegrationDashboard
} else if aH.IntegrationsController.IsInstalledIntegrationDashboardID(id) {
integrationDashboard, apiErr := aH.IntegrationsController.GetInstalledIntegrationDashboardById(ctx, orgID, id)
if apiErr != nil {
@@ -1293,13 +1279,11 @@ func (aH *APIHandler) List(rw http.ResponseWriter, r *http.Request) {
dashboards = append(dashboards, installedIntegrationDashboards...)
}
for _, provider := range aH.cloudIntegrationsRegistry {
cloudIntegrationDashboards, err := provider.GetAvailableDashboards(ctx, orgID)
if err != nil {
zap.L().Error("failed to get dashboards for cloud integrations", zap.Error(apiErr))
} else {
dashboards = append(dashboards, cloudIntegrationDashboards...)
}
cloudIntegrationDashboards, apiErr := aH.CloudIntegrationsController.AvailableDashboards(ctx, orgID)
if apiErr != nil {
zap.L().Error("failed to get dashboards for cloud integrations", zap.Error(apiErr))
} else {
dashboards = append(dashboards, cloudIntegrationDashboards...)
}
gettableDashboards, err := dashboardtypes.NewGettableDashboardsFromDashboards(dashboards)
@@ -3275,15 +3259,15 @@ func (aH *APIHandler) GetIntegrationConnectionStatus(w http.ResponseWriter, r *h
lookbackSeconds = 15 * 60
}
connectionStatus, err := aH.calculateConnectionStatus(
connectionStatus, apiErr := aH.calculateConnectionStatus(
r.Context(), orgID, connectionTests, lookbackSeconds,
)
if err != nil {
render.Error(w, err)
if apiErr != nil {
RespondError(w, apiErr, "Failed to calculate integration connection status")
return
}
render.Success(w, http.StatusOK, connectionStatus)
aH.Respond(w, connectionStatus)
}
func (aH *APIHandler) calculateConnectionStatus(
@@ -3291,11 +3275,10 @@ func (aH *APIHandler) calculateConnectionStatus(
orgID valuer.UUID,
connectionTests *integrations.IntegrationConnectionTests,
lookbackSeconds int64,
) (*integrations.IntegrationConnectionStatus, error) {
) (*integrations.IntegrationConnectionStatus, *model.ApiError) {
// Calculate connection status for signals in parallel
result := &integrations.IntegrationConnectionStatus{}
// TODO: migrate to errors package
errors := []*model.ApiError{}
var resultLock sync.Mutex
@@ -3493,14 +3476,12 @@ func (aH *APIHandler) UninstallIntegration(w http.ResponseWriter, r *http.Reques
aH.Respond(w, map[string]interface{}{})
}
// RegisterCloudIntegrationsRoutes register routes for cloud provider integrations
// cloud provider integrations
func (aH *APIHandler) RegisterCloudIntegrationsRoutes(router *mux.Router, am *middleware.AuthZ) {
subRouter := router.PathPrefix("/api/v1/cloud-integrations").Subrouter()
subRouter.Use(middleware.NewRecovery(aH.Signoz.Instrumentation.Logger()).Wrap)
subRouter.HandleFunc(
"/{cloudProvider}/accounts/generate-connection-url", am.EditAccess(aH.CloudIntegrationsGenerateConnectionArtifact),
"/{cloudProvider}/accounts/generate-connection-url", am.EditAccess(aH.CloudIntegrationsGenerateConnectionUrl),
).Methods(http.MethodPost)
subRouter.HandleFunc(
@@ -3534,199 +3515,170 @@ func (aH *APIHandler) RegisterCloudIntegrationsRoutes(router *mux.Router, am *mi
subRouter.HandleFunc(
"/{cloudProvider}/services/{serviceId}/config", am.EditAccess(aH.CloudIntegrationsUpdateServiceConfig),
).Methods(http.MethodPost)
}
func (aH *APIHandler) CloudIntegrationsGenerateConnectionArtifact(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
func (aH *APIHandler) CloudIntegrationsListConnectedAccounts(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
resp, apiErr := aH.CloudIntegrationsController.ListConnectedAccounts(
r.Context(), claims.OrgID, cloudProvider,
)
if apiErr != nil {
RespondError(w, apiErr, nil)
return
}
reqBody, err := io.ReadAll(r.Body)
if err != nil {
render.Error(w, errors.WrapInternalf(err, errors.CodeInternal, "failed to read request body"))
return
}
resp, err := aH.cloudIntegrationsRegistry[cloudProvider].GenerateConnectionArtifact(r.Context(), &integrationtypes.PostableConnectionArtifact{
OrgID: claims.OrgID,
Data: reqBody,
})
if err != nil {
aH.Signoz.Instrumentation.Logger().ErrorContext(r.Context(),
"failed to generate connection artifact for cloud integration",
slog.String("cloudProvider", cloudProviderString),
slog.String("orgID", claims.OrgID),
)
render.Error(w, err)
return
}
render.Success(w, http.StatusOK, resp)
aH.Respond(w, resp)
}
func (aH *APIHandler) CloudIntegrationsListConnectedAccounts(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
func (aH *APIHandler) CloudIntegrationsGenerateConnectionUrl(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
req := cloudintegrations.GenerateConnectionUrlRequest{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
resp, err := aH.cloudIntegrationsRegistry[cloudProvider].ListConnectedAccounts(r.Context(), claims.OrgID)
if err != nil {
render.Error(w, err)
result, apiErr := aH.CloudIntegrationsController.GenerateConnectionUrl(
r.Context(), claims.OrgID, cloudProvider, req,
)
if apiErr != nil {
RespondError(w, apiErr, nil)
return
}
render.Success(w, http.StatusOK, resp)
aH.Respond(w, result)
}
func (aH *APIHandler) CloudIntegrationsGetAccountStatus(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
return
}
func (aH *APIHandler) CloudIntegrationsGetAccountStatus(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
accountId := mux.Vars(r)["accountId"]
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
resp, err := aH.cloudIntegrationsRegistry[cloudProvider].GetAccountStatus(r.Context(), claims.OrgID, accountId)
if err != nil {
render.Error(w, err)
resp, apiErr := aH.CloudIntegrationsController.GetAccountStatus(
r.Context(), claims.OrgID, cloudProvider, accountId,
)
if apiErr != nil {
RespondError(w, apiErr, nil)
return
}
render.Success(w, http.StatusOK, resp)
aH.Respond(w, resp)
}
func (aH *APIHandler) CloudIntegrationsAgentCheckIn(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
func (aH *APIHandler) CloudIntegrationsAgentCheckIn(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
req := cloudintegrations.AgentCheckInRequest{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
result, err := aH.CloudIntegrationsController.CheckInAsAgent(
r.Context(), claims.OrgID, cloudProvider, req,
)
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
return
}
req := new(integrationtypes.PostableAgentCheckInPayload)
if err = json.NewDecoder(r.Body).Decode(req); err != nil {
render.Error(w, errors.WrapInvalidInputf(err, errors.CodeInvalidInput, "invalid request body"))
return
}
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
return
}
req.OrgID = claims.OrgID
resp, err := aH.cloudIntegrationsRegistry[cloudProvider].AgentCheckIn(r.Context(), req)
if err != nil {
render.Error(w, err)
return
}
render.Success(w, http.StatusOK, resp)
aH.Respond(w, result)
}
func (aH *APIHandler) CloudIntegrationsUpdateAccountConfig(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
return
}
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
return
}
func (aH *APIHandler) CloudIntegrationsUpdateAccountConfig(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
accountId := mux.Vars(r)["accountId"]
reqBody, err := io.ReadAll(r.Body)
if err != nil {
render.Error(w, errors.WrapInternalf(err, errors.CodeInternal, "failed to read request body"))
req := cloudintegrations.UpdateAccountConfigRequest{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}
resp, err := aH.cloudIntegrationsRegistry[cloudProvider].UpdateAccountConfig(r.Context(), &integrationtypes.PatchableAccountConfig{
OrgID: claims.OrgID,
AccountId: accountId,
Data: reqBody,
})
if err != nil {
render.Error(w, err)
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
render.Success(w, http.StatusOK, resp)
return
result, apiErr := aH.CloudIntegrationsController.UpdateAccountConfig(
r.Context(), claims.OrgID, cloudProvider, accountId, req,
)
if apiErr != nil {
RespondError(w, apiErr, nil)
return
}
aH.Respond(w, result)
}
func (aH *APIHandler) CloudIntegrationsDisconnectAccount(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
return
}
func (aH *APIHandler) CloudIntegrationsDisconnectAccount(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
accountId := mux.Vars(r)["accountId"]
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
result, err := aH.cloudIntegrationsRegistry[cloudProvider].DisconnectAccount(r.Context(), claims.OrgID, accountId)
if err != nil {
render.Error(w, err)
result, apiErr := aH.CloudIntegrationsController.DisconnectAccount(
r.Context(), claims.OrgID, cloudProvider, accountId,
)
if apiErr != nil {
RespondError(w, apiErr, nil)
return
}
render.Success(w, http.StatusOK, result)
aH.Respond(w, result)
}
func (aH *APIHandler) CloudIntegrationsListServices(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
return
}
func (aH *APIHandler) CloudIntegrationsListServices(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
var cloudAccountId *string
@@ -3735,22 +3687,26 @@ func (aH *APIHandler) CloudIntegrationsListServices(w http.ResponseWriter, r *ht
cloudAccountId = &cloudAccountIdQP
}
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
resp, err := aH.cloudIntegrationsRegistry[cloudProvider].ListServices(r.Context(), claims.OrgID, cloudAccountId)
if err != nil {
render.Error(w, err)
resp, apiErr := aH.CloudIntegrationsController.ListServices(
r.Context(), claims.OrgID, cloudProvider, cloudAccountId,
)
if apiErr != nil {
RespondError(w, apiErr, nil)
return
}
render.Success(w, http.StatusOK, resp)
aH.Respond(w, resp)
}
func (aH *APIHandler) CloudIntegrationsGetServiceDetails(w http.ResponseWriter, r *http.Request) {
func (aH *APIHandler) CloudIntegrationsGetServiceDetails(
w http.ResponseWriter, r *http.Request,
) {
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
@@ -3762,14 +3718,7 @@ func (aH *APIHandler) CloudIntegrationsGetServiceDetails(w http.ResponseWriter,
return
}
cloudProviderString := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
return
}
cloudProvider := mux.Vars(r)["cloudProvider"]
serviceId := mux.Vars(r)["serviceId"]
var cloudAccountId *string
@@ -3779,59 +3728,270 @@ func (aH *APIHandler) CloudIntegrationsGetServiceDetails(w http.ResponseWriter,
cloudAccountId = &cloudAccountIdQP
}
resp, err := aH.cloudIntegrationsRegistry[cloudProvider].GetServiceDetails(r.Context(), &integrationtypes.GetServiceDetailsReq{
OrgID: orgID,
ServiceId: serviceId,
CloudAccountID: cloudAccountId,
})
if err != nil {
render.Error(w, err)
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
render.Success(w, http.StatusOK, resp)
return
}
func (aH *APIHandler) CloudIntegrationsUpdateServiceConfig(w http.ResponseWriter, r *http.Request) {
cloudProviderString := mux.Vars(r)["cloudProvider"]
cloudProvider, err := integrationtypes.NewCloudProvider(cloudProviderString)
if err != nil {
render.Error(w, err)
return
}
serviceId := mux.Vars(r)["serviceId"]
claims, err := authtypes.ClaimsFromContext(r.Context())
if err != nil {
render.Error(w, err)
return
}
reqBody, err := io.ReadAll(r.Body)
if err != nil {
render.Error(w, errors.WrapInternalf(err,
errors.CodeInternal,
"failed to read update service config request body",
))
return
}
result, err := aH.cloudIntegrationsRegistry[cloudProvider].UpdateServiceConfig(
r.Context(), &integrationtypes.PatchableServiceConfig{
OrgID: claims.OrgID,
ServiceId: serviceId,
Config: reqBody,
},
resp, err := aH.CloudIntegrationsController.GetServiceDetails(
r.Context(), claims.OrgID, cloudProvider, serviceId, cloudAccountId,
)
if err != nil {
render.Error(w, err)
return
}
render.Success(w, http.StatusOK, result)
// Add connection status for the 2 signals.
if cloudAccountId != nil {
connStatus, apiErr := aH.calculateCloudIntegrationServiceConnectionStatus(
r.Context(), orgID, cloudProvider, *cloudAccountId, resp,
)
if apiErr != nil {
RespondError(w, apiErr, nil)
return
}
resp.ConnectionStatus = connStatus
}
aH.Respond(w, resp)
}
func (aH *APIHandler) calculateCloudIntegrationServiceConnectionStatus(
ctx context.Context,
orgID valuer.UUID,
cloudProvider string,
cloudAccountId string,
svcDetails *cloudintegrations.ServiceDetails,
) (*cloudintegrations.ServiceConnectionStatus, *model.ApiError) {
if cloudProvider != "aws" {
// TODO(Raj): Make connection check generic for all providers in a follow up change
return nil, model.BadRequest(
fmt.Errorf("unsupported cloud provider: %s", cloudProvider),
)
}
telemetryCollectionStrategy := svcDetails.Strategy
if telemetryCollectionStrategy == nil {
return nil, model.InternalError(fmt.Errorf(
"service doesn't have telemetry collection strategy: %s", svcDetails.Id,
))
}
result := &cloudintegrations.ServiceConnectionStatus{}
errors := []*model.ApiError{}
var resultLock sync.Mutex
var wg sync.WaitGroup
// Calculate metrics connection status
if telemetryCollectionStrategy.AWSMetrics != nil {
wg.Add(1)
go func() {
defer wg.Done()
metricsConnStatus, apiErr := aH.calculateAWSIntegrationSvcMetricsConnectionStatus(
ctx, cloudAccountId, telemetryCollectionStrategy.AWSMetrics, svcDetails.DataCollected.Metrics,
)
resultLock.Lock()
defer resultLock.Unlock()
if apiErr != nil {
errors = append(errors, apiErr)
} else {
result.Metrics = metricsConnStatus
}
}()
}
// Calculate logs connection status
if telemetryCollectionStrategy.AWSLogs != nil {
wg.Add(1)
go func() {
defer wg.Done()
logsConnStatus, apiErr := aH.calculateAWSIntegrationSvcLogsConnectionStatus(
ctx, orgID, cloudAccountId, telemetryCollectionStrategy.AWSLogs,
)
resultLock.Lock()
defer resultLock.Unlock()
if apiErr != nil {
errors = append(errors, apiErr)
} else {
result.Logs = logsConnStatus
}
}()
}
wg.Wait()
if len(errors) > 0 {
return nil, errors[0]
}
return result, nil
}
func (aH *APIHandler) calculateAWSIntegrationSvcMetricsConnectionStatus(
ctx context.Context,
cloudAccountId string,
strategy *services.AWSMetricsStrategy,
metricsCollectedBySvc []services.CollectedMetric,
) (*cloudintegrations.SignalConnectionStatus, *model.ApiError) {
if strategy == nil || len(strategy.StreamFilters) < 1 {
return nil, nil
}
expectedLabelValues := map[string]string{
"cloud_provider": "aws",
"cloud_account_id": cloudAccountId,
}
metricsNamespace := strategy.StreamFilters[0].Namespace
metricsNamespaceParts := strings.Split(metricsNamespace, "/")
if len(metricsNamespaceParts) >= 2 {
expectedLabelValues["service_namespace"] = metricsNamespaceParts[0]
expectedLabelValues["service_name"] = metricsNamespaceParts[1]
} else {
// metrics for single word namespaces like "CWAgent" do not
// have the service_namespace label populated
expectedLabelValues["service_name"] = metricsNamespaceParts[0]
}
metricNamesCollectedBySvc := []string{}
for _, cm := range metricsCollectedBySvc {
metricNamesCollectedBySvc = append(metricNamesCollectedBySvc, cm.Name)
}
statusForLastReceivedMetric, apiErr := aH.reader.GetLatestReceivedMetric(
ctx, metricNamesCollectedBySvc, expectedLabelValues,
)
if apiErr != nil {
return nil, apiErr
}
if statusForLastReceivedMetric != nil {
return &cloudintegrations.SignalConnectionStatus{
LastReceivedTsMillis: statusForLastReceivedMetric.LastReceivedTsMillis,
LastReceivedFrom: "signoz-aws-integration",
}, nil
}
return nil, nil
}
func (aH *APIHandler) calculateAWSIntegrationSvcLogsConnectionStatus(
ctx context.Context,
orgID valuer.UUID,
cloudAccountId string,
strategy *services.AWSLogsStrategy,
) (*cloudintegrations.SignalConnectionStatus, *model.ApiError) {
if strategy == nil || len(strategy.Subscriptions) < 1 {
return nil, nil
}
logGroupNamePrefix := strategy.Subscriptions[0].LogGroupNamePrefix
if len(logGroupNamePrefix) < 1 {
return nil, nil
}
logsConnTestFilter := &v3.FilterSet{
Operator: "AND",
Items: []v3.FilterItem{
{
Key: v3.AttributeKey{
Key: "cloud.account.id",
DataType: v3.AttributeKeyDataTypeString,
Type: v3.AttributeKeyTypeResource,
},
Operator: "=",
Value: cloudAccountId,
},
{
Key: v3.AttributeKey{
Key: "aws.cloudwatch.log_group_name",
DataType: v3.AttributeKeyDataTypeString,
Type: v3.AttributeKeyTypeResource,
},
Operator: "like",
Value: logGroupNamePrefix + "%",
},
},
}
// TODO(Raj): Receive this as a param from UI in the future.
lookbackSeconds := int64(30 * 60)
qrParams := &v3.QueryRangeParamsV3{
Start: time.Now().UnixMilli() - (lookbackSeconds * 1000),
End: time.Now().UnixMilli(),
CompositeQuery: &v3.CompositeQuery{
PanelType: v3.PanelTypeList,
QueryType: v3.QueryTypeBuilder,
BuilderQueries: map[string]*v3.BuilderQuery{
"A": {
PageSize: 1,
Filters: logsConnTestFilter,
QueryName: "A",
DataSource: v3.DataSourceLogs,
Expression: "A",
AggregateOperator: v3.AggregateOperatorNoOp,
},
},
},
}
queryRes, _, err := aH.querier.QueryRange(
ctx, orgID, qrParams,
)
if err != nil {
return nil, model.InternalError(fmt.Errorf(
"could not query for integration connection status: %w", err,
))
}
if len(queryRes) > 0 && queryRes[0].List != nil && len(queryRes[0].List) > 0 {
lastLog := queryRes[0].List[0]
return &cloudintegrations.SignalConnectionStatus{
LastReceivedTsMillis: lastLog.Timestamp.UnixMilli(),
LastReceivedFrom: "signoz-aws-integration",
}, nil
}
return nil, nil
}
func (aH *APIHandler) CloudIntegrationsUpdateServiceConfig(
w http.ResponseWriter, r *http.Request,
) {
cloudProvider := mux.Vars(r)["cloudProvider"]
serviceId := mux.Vars(r)["serviceId"]
req := cloudintegrations.UpdateServiceConfigRequest{}
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
RespondError(w, model.BadRequest(err), nil)
return
}
claims, errv2 := authtypes.ClaimsFromContext(r.Context())
if errv2 != nil {
render.Error(w, errv2)
return
}
result, err := aH.CloudIntegrationsController.UpdateServiceConfig(
r.Context(), claims.OrgID, cloudProvider, serviceId, &req,
)
if err != nil {
render.Error(w, err)
return
}
aH.Respond(w, result)
}
// logs

View File

@@ -11,7 +11,6 @@ import (
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/types/pipelinetypes"
ruletypes "github.com/SigNoz/signoz/pkg/types/ruletypes"
"github.com/SigNoz/signoz/pkg/valuer"
@@ -108,7 +107,7 @@ type IntegrationsListItem struct {
type Integration struct {
IntegrationDetails
Installation *integrationtypes.InstalledIntegration `json:"installation"`
Installation *types.InstalledIntegration `json:"installation"`
}
type Manager struct {
@@ -224,7 +223,7 @@ func (m *Manager) InstallIntegration(
ctx context.Context,
orgId string,
integrationId string,
config integrationtypes.InstalledIntegrationConfig,
config types.InstalledIntegrationConfig,
) (*IntegrationsListItem, *model.ApiError) {
integrationDetails, apiErr := m.getIntegrationDetails(ctx, integrationId)
if apiErr != nil {
@@ -430,7 +429,7 @@ func (m *Manager) getInstalledIntegration(
ctx context.Context,
orgId string,
integrationId string,
) (*integrationtypes.InstalledIntegration, *model.ApiError) {
) (*types.InstalledIntegration, *model.ApiError) {
iis, apiErr := m.installedIntegrationsRepo.get(
ctx, orgId, []string{integrationId},
)
@@ -458,7 +457,7 @@ func (m *Manager) getInstalledIntegrations(
return nil, apiErr
}
installedTypes := utils.MapSlice(installations, func(i integrationtypes.InstalledIntegration) string {
installedTypes := utils.MapSlice(installations, func(i types.InstalledIntegration) string {
return i.Type
})
integrationDetails, apiErr := m.availableIntegrationsRepo.get(ctx, installedTypes)

View File

@@ -4,22 +4,22 @@ import (
"context"
"github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/types"
)
type InstalledIntegrationsRepo interface {
list(ctx context.Context, orgId string) ([]integrationtypes.InstalledIntegration, *model.ApiError)
list(ctx context.Context, orgId string) ([]types.InstalledIntegration, *model.ApiError)
get(
ctx context.Context, orgId string, integrationTypes []string,
) (map[string]integrationtypes.InstalledIntegration, *model.ApiError)
) (map[string]types.InstalledIntegration, *model.ApiError)
upsert(
ctx context.Context,
orgId string,
integrationType string,
config integrationtypes.InstalledIntegrationConfig,
) (*integrationtypes.InstalledIntegration, *model.ApiError)
config types.InstalledIntegrationConfig,
) (*types.InstalledIntegration, *model.ApiError)
delete(ctx context.Context, orgId string, integrationType string) *model.ApiError
}

View File

@@ -7,7 +7,6 @@ import (
"github.com/SigNoz/signoz/pkg/query-service/model"
"github.com/SigNoz/signoz/pkg/sqlstore"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/integrationtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/uptrace/bun"
)
@@ -27,8 +26,8 @@ func NewInstalledIntegrationsSqliteRepo(store sqlstore.SQLStore) (
func (r *InstalledIntegrationsSqliteRepo) list(
ctx context.Context,
orgId string,
) ([]integrationtypes.InstalledIntegration, *model.ApiError) {
integrations := []integrationtypes.InstalledIntegration{}
) ([]types.InstalledIntegration, *model.ApiError) {
integrations := []types.InstalledIntegration{}
err := r.store.BunDB().NewSelect().
Model(&integrations).
@@ -45,8 +44,8 @@ func (r *InstalledIntegrationsSqliteRepo) list(
func (r *InstalledIntegrationsSqliteRepo) get(
ctx context.Context, orgId string, integrationTypes []string,
) (map[string]integrationtypes.InstalledIntegration, *model.ApiError) {
integrations := []integrationtypes.InstalledIntegration{}
) (map[string]types.InstalledIntegration, *model.ApiError) {
integrations := []types.InstalledIntegration{}
typeValues := []interface{}{}
for _, integrationType := range integrationTypes {
@@ -63,7 +62,7 @@ func (r *InstalledIntegrationsSqliteRepo) get(
))
}
result := map[string]integrationtypes.InstalledIntegration{}
result := map[string]types.InstalledIntegration{}
for _, ii := range integrations {
result[ii.Type] = ii
}
@@ -75,10 +74,10 @@ func (r *InstalledIntegrationsSqliteRepo) upsert(
ctx context.Context,
orgId string,
integrationType string,
config integrationtypes.InstalledIntegrationConfig,
) (*integrationtypes.InstalledIntegration, *model.ApiError) {
config types.InstalledIntegrationConfig,
) (*types.InstalledIntegration, *model.ApiError) {
integration := integrationtypes.InstalledIntegration{
integration := types.InstalledIntegration{
Identifiable: types.Identifiable{
ID: valuer.GenerateUUID(),
},
@@ -115,7 +114,7 @@ func (r *InstalledIntegrationsSqliteRepo) delete(
ctx context.Context, orgId string, integrationType string,
) *model.ApiError {
_, dbErr := r.store.BunDB().NewDelete().
Model(&integrationtypes.InstalledIntegration{}).
Model(&types.InstalledIntegration{}).
Where("type = ?", integrationType).
Where("org_id = ?", orgId).
Exec(ctx)

View File

@@ -25,6 +25,7 @@ import (
"github.com/SigNoz/signoz/pkg/querier"
"github.com/SigNoz/signoz/pkg/query-service/agentConf"
"github.com/SigNoz/signoz/pkg/query-service/app/clickhouseReader"
"github.com/SigNoz/signoz/pkg/query-service/app/cloudintegrations"
"github.com/SigNoz/signoz/pkg/query-service/app/integrations"
"github.com/SigNoz/signoz/pkg/query-service/app/logparsingpipeline"
"github.com/SigNoz/signoz/pkg/query-service/app/opamp"
@@ -69,6 +70,11 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
return nil, err
}
cloudIntegrationsController, err := cloudintegrations.NewController(signoz.SQLStore)
if err != nil {
return nil, err
}
cacheForTraceDetail, err := memorycache.New(context.TODO(), signoz.Instrumentation.ToProviderSettings(), cache.Config{
Provider: "memory",
Memory: cache.Memory{
@@ -120,13 +126,13 @@ func NewServer(config signoz.Config, signoz *signoz.SigNoz) (*Server, error) {
Reader: reader,
RuleManager: rm,
IntegrationsController: integrationsController,
CloudIntegrationsController: cloudIntegrationsController,
LogsParsingPipelineController: logParsingPipelineController,
FluxInterval: config.Querier.FluxInterval,
AlertmanagerAPI: alertmanager.NewAPI(signoz.Alertmanager),
LicensingAPI: nooplicensing.NewLicenseAPI(),
Signoz: signoz,
QueryParserAPI: queryparser.NewAPI(signoz.Instrumentation.ToProviderSettings(), signoz.QueryParser),
Logger: signoz.Instrumentation.Logger(),
}, config)
if err != nil {
return nil, err

View File

@@ -1,13 +0,0 @@
package utils
import (
"runtime/debug"
)
func RecoverPanic(callback func(err interface{}, stack []byte)) {
if r := recover(); r != nil {
if callback != nil {
callback(r, debug.Stack())
}
}
}

247
pkg/types/integration.go Normal file
View File

@@ -0,0 +1,247 @@
package types
import (
"database/sql/driver"
"encoding/json"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/uptrace/bun"
)
type IntegrationUserEmail string
const (
AWSIntegrationUserEmail IntegrationUserEmail = "aws-integration@signoz.io"
)
var AllIntegrationUserEmails = []IntegrationUserEmail{
AWSIntegrationUserEmail,
}
// --------------------------------------------------------------------------
// Normal integration uses just the installed_integration table
// --------------------------------------------------------------------------
type InstalledIntegration struct {
bun.BaseModel `bun:"table:installed_integration"`
Identifiable
Type string `json:"type" bun:"type,type:text,unique:org_id_type"`
Config InstalledIntegrationConfig `json:"config" bun:"config,type:text"`
InstalledAt time.Time `json:"installed_at" bun:"installed_at,default:current_timestamp"`
OrgID string `json:"org_id" bun:"org_id,type:text,unique:org_id_type,references:organizations(id),on_delete:cascade"`
}
type InstalledIntegrationConfig map[string]interface{}
// For serializing from db
func (c *InstalledIntegrationConfig) Scan(src interface{}) error {
var data []byte
switch v := src.(type) {
case []byte:
data = v
case string:
data = []byte(v)
default:
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
}
return json.Unmarshal(data, c)
}
// For serializing to db
func (c *InstalledIntegrationConfig) Value() (driver.Value, error) {
filterSetJson, err := json.Marshal(c)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "could not serialize integration config to JSON")
}
return filterSetJson, nil
}
// --------------------------------------------------------------------------
// Cloud integration uses the cloud_integration table
// and cloud_integrations_service table
// --------------------------------------------------------------------------
type CloudIntegration struct {
bun.BaseModel `bun:"table:cloud_integration"`
Identifiable
TimeAuditable
Provider string `json:"provider" bun:"provider,type:text,unique:provider_id"`
Config *AccountConfig `json:"config" bun:"config,type:text"`
AccountID *string `json:"account_id" bun:"account_id,type:text"`
LastAgentReport *AgentReport `json:"last_agent_report" bun:"last_agent_report,type:text"`
RemovedAt *time.Time `json:"removed_at" bun:"removed_at,type:timestamp,nullzero"`
OrgID string `bun:"org_id,type:text,unique:provider_id"`
}
func (a *CloudIntegration) Status() AccountStatus {
status := AccountStatus{}
if a.LastAgentReport != nil {
lastHeartbeat := a.LastAgentReport.TimestampMillis
status.Integration.LastHeartbeatTsMillis = &lastHeartbeat
}
return status
}
func (a *CloudIntegration) Account() Account {
ca := Account{Id: a.ID.StringValue(), Status: a.Status()}
if a.AccountID != nil {
ca.CloudAccountId = *a.AccountID
}
if a.Config != nil {
ca.Config = *a.Config
} else {
ca.Config = DefaultAccountConfig()
}
return ca
}
type Account struct {
Id string `json:"id"`
CloudAccountId string `json:"cloud_account_id"`
Config AccountConfig `json:"config"`
Status AccountStatus `json:"status"`
}
type AccountStatus struct {
Integration AccountIntegrationStatus `json:"integration"`
}
type AccountIntegrationStatus struct {
LastHeartbeatTsMillis *int64 `json:"last_heartbeat_ts_ms"`
}
func DefaultAccountConfig() AccountConfig {
return AccountConfig{
EnabledRegions: []string{},
}
}
type AccountConfig struct {
EnabledRegions []string `json:"regions"`
}
// For serializing from db
func (c *AccountConfig) Scan(src any) error {
var data []byte
switch v := src.(type) {
case []byte:
data = v
case string:
data = []byte(v)
default:
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
}
return json.Unmarshal(data, c)
}
// For serializing to db
func (c *AccountConfig) Value() (driver.Value, error) {
if c == nil {
return nil, errors.NewInternalf(errors.CodeInternal, "cloud account config is nil")
}
serialized, err := json.Marshal(c)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "couldn't serialize cloud account config to JSON")
}
// Return as string instead of []byte to ensure PostgreSQL stores as text, not bytea
return string(serialized), nil
}
type AgentReport struct {
TimestampMillis int64 `json:"timestamp_millis"`
Data map[string]any `json:"data"`
}
// For serializing from db
func (r *AgentReport) Scan(src any) error {
var data []byte
switch v := src.(type) {
case []byte:
data = v
case string:
data = []byte(v)
default:
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
}
return json.Unmarshal(data, r)
}
// For serializing to db
func (r *AgentReport) Value() (driver.Value, error) {
if r == nil {
return nil, errors.NewInternalf(errors.CodeInternal, "agent report is nil")
}
serialized, err := json.Marshal(r)
if err != nil {
return nil, errors.WrapInternalf(
err, errors.CodeInternal, "couldn't serialize agent report to JSON",
)
}
// Return as string instead of []byte to ensure PostgreSQL stores as text, not bytea
return string(serialized), nil
}
type CloudIntegrationService struct {
bun.BaseModel `bun:"table:cloud_integration_service,alias:cis"`
Identifiable
TimeAuditable
Type string `bun:"type,type:text,notnull,unique:cloud_integration_id_type"`
Config CloudServiceConfig `bun:"config,type:text"`
CloudIntegrationID string `bun:"cloud_integration_id,type:text,notnull,unique:cloud_integration_id_type,references:cloud_integrations(id),on_delete:cascade"`
}
type CloudServiceLogsConfig struct {
Enabled bool `json:"enabled"`
S3Buckets map[string][]string `json:"s3_buckets,omitempty"`
}
type CloudServiceMetricsConfig struct {
Enabled bool `json:"enabled"`
}
type CloudServiceConfig struct {
Logs *CloudServiceLogsConfig `json:"logs,omitempty"`
Metrics *CloudServiceMetricsConfig `json:"metrics,omitempty"`
}
// For serializing from db
func (c *CloudServiceConfig) Scan(src any) error {
var data []byte
switch src := src.(type) {
case []byte:
data = src
case string:
data = []byte(src)
default:
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
}
return json.Unmarshal(data, c)
}
// For serializing to db
func (c *CloudServiceConfig) Value() (driver.Value, error) {
if c == nil {
return nil, errors.NewInternalf(errors.CodeInternal, "cloud service config is nil")
}
serialized, err := json.Marshal(c)
if err != nil {
return nil, errors.WrapInternalf(
err, errors.CodeInternal, "couldn't serialize cloud service config to JSON",
)
}
// Return as string instead of []byte to ensure PostgreSQL stores as text, not bytea
return string(serialized), nil
}

View File

@@ -1,396 +0,0 @@
package integrationtypes
import (
"context"
"database/sql/driver"
"encoding/json"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/uptrace/bun"
)
// Generic utility functions for JSON serialization/deserialization
// UnmarshalJSON is a generic function to unmarshal JSON data into any type
func UnmarshalJSON[T any](src []byte, target *T) error {
err := json.Unmarshal(src, target)
if err != nil {
return errors.WrapInternalf(
err, errors.CodeInternal, "couldn't deserialize JSON",
)
}
return nil
}
// MarshalJSON is a generic function to marshal any type to JSON
func MarshalJSON[T any](source *T) ([]byte, error) {
if source == nil {
return nil, errors.NewInternalf(errors.CodeInternal, "source is nil")
}
serialized, err := json.Marshal(source)
if err != nil {
return nil, errors.WrapInternalf(
err, errors.CodeInternal, "couldn't serialize to JSON",
)
}
return serialized, nil
}
// CloudProvider defines the interface to be implemented by different cloud providers.
// This is generic interface so it will be accepting and returning generic types instead of concrete.
// It's the cloud provider's responsibility to cast them to appropriate types and validate
type CloudProvider interface {
GetName() CloudProviderType
AgentCheckIn(ctx context.Context, req *PostableAgentCheckInPayload) (any, error)
GenerateConnectionArtifact(ctx context.Context, req *PostableConnectionArtifact) (any, error)
GetAccountStatus(ctx context.Context, orgID, accountID string) (*GettableAccountStatus, error)
ListServices(ctx context.Context, orgID string, accountID *string) (any, error) // returns either GettableAWSServices
GetServiceDetails(ctx context.Context, req *GetServiceDetailsReq) (any, error)
ListConnectedAccounts(ctx context.Context, orgID string) (*GettableConnectedAccountsList, error)
GetDashboard(ctx context.Context, req *GettableDashboard) (*dashboardtypes.Dashboard, error)
GetAvailableDashboards(ctx context.Context, orgID valuer.UUID) ([]*dashboardtypes.Dashboard, error)
UpdateAccountConfig(ctx context.Context, req *PatchableAccountConfig) (any, error) // req can be either PatchableAWSAccountConfig
UpdateServiceConfig(ctx context.Context, req *PatchableServiceConfig) (any, error)
DisconnectAccount(ctx context.Context, orgID, accountID string) (*CloudIntegration, error)
}
type GettableDashboard struct {
ID string
OrgID valuer.UUID
}
type GettableCloudIntegrationConnectionParams struct {
IngestionUrl string `json:"ingestion_url,omitempty"`
IngestionKey string `json:"ingestion_key,omitempty"`
SigNozAPIUrl string `json:"signoz_api_url,omitempty"`
SigNozAPIKey string `json:"signoz_api_key,omitempty"`
}
type GettableIngestionKey struct {
Name string `json:"name"`
Value string `json:"value"`
// other attributes from gateway response not included here since they are not being used.
}
type GettableIngestionKeysSearch struct {
Status string `json:"status"`
Data []GettableIngestionKey `json:"data"`
Error string `json:"error"`
}
type GettableCreateIngestionKey struct {
Status string `json:"status"`
Data GettableIngestionKey `json:"data"`
Error string `json:"error"`
}
type GettableDeployment struct {
Name string `json:"name"`
ClusterInfo struct {
Region struct {
DNS string `json:"dns"`
} `json:"region"`
} `json:"cluster"`
}
type GettableConnectedAccountsList struct {
Accounts []*Account `json:"accounts"`
}
// SigNozAWSAgentConfig represents requirements for agent deployment in user's AWS account
type SigNozAWSAgentConfig struct {
// The region in which SigNoz agent should be installed.
Region string `json:"region"`
IngestionUrl string `json:"ingestion_url"`
IngestionKey string `json:"ingestion_key"`
SigNozAPIUrl string `json:"signoz_api_url"`
SigNozAPIKey string `json:"signoz_api_key"`
Version string `json:"version,omitempty"`
}
type PostableConnectionArtifact struct {
OrgID string
Data []byte // either PostableAWSConnectionUrl
}
type PostableConnectionArtifactTyped[AgentConfigT any, AccountConfigT any] struct {
AccountId *string `json:"account_id,omitempty"` // Optional. To be specified for updates.
AgentConfig *AgentConfigT `json:"agent_config"`
AccountConfig *AccountConfigT `json:"account_config"`
}
type PostableAWSConnectionUrl = PostableConnectionArtifactTyped[SigNozAWSAgentConfig, AWSAccountConfig]
// GettableConnectionArtifact represents base structure for connection artifacts
type GettableConnectionArtifact[T any] struct {
AccountId string `json:"account_id"`
Artifact T `json:",inline"`
}
type GettableAWSConnectionArtifact struct {
ConnectionUrl string `json:"connection_url"`
}
type GettableAWSConnectionUrl struct {
AccountId string `json:"account_id"`
ConnectionUrl string `json:"connection_url"`
}
type GettableAccountStatus struct {
Id string `json:"id"`
CloudAccountId *string `json:"cloud_account_id,omitempty"`
Status AccountStatus `json:"status"`
}
type PostableAgentCheckInPayload struct {
ID string `json:"account_id"`
AccountID string `json:"cloud_account_id"`
// Arbitrary cloud specific Agent data
Data map[string]any `json:"data,omitempty"`
OrgID string `json:"-"`
}
type AWSAgentIntegrationConfig struct {
EnabledRegions []string `json:"enabled_regions"`
TelemetryCollectionStrategy *AWSCollectionStrategy `json:"telemetry,omitempty"`
}
type GettableAgentCheckIn[T any] struct {
AccountId string `json:"account_id"`
CloudAccountId string `json:"cloud_account_id"`
RemovedAt *time.Time `json:"removed_at"`
IntegrationConfig T `json:"integration_config"`
}
type GettableAWSAgentCheckIn = GettableAgentCheckIn[AWSAgentIntegrationConfig]
type PatchableServiceConfig struct {
OrgID string `json:"org_id"`
ServiceId string `json:"service_id"`
Config []byte `json:"config"` // json serialized config
}
type UpdatableCloudServiceConfig[T any] struct {
CloudAccountId string `json:"cloud_account_id"`
Config *T `json:"config"`
}
type UpdatableAWSCloudServiceConfig = UpdatableCloudServiceConfig[AWSCloudServiceConfig]
type AWSCloudServiceConfig struct {
Logs *AWSCloudServiceLogsConfig `json:"logs,omitempty"`
Metrics *AWSCloudServiceMetricsConfig `json:"metrics,omitempty"`
}
func (a *AWSCloudServiceConfig) Validate(def *AWSDefinition) error {
if def.Id != S3Sync && a.Logs != nil && a.Logs.S3Buckets != nil {
return errors.NewInvalidInputf(errors.CodeInvalidInput, "s3 buckets can only be added to service-type[%s]", S3Sync)
} else if def.Id == S3Sync && a.Logs != nil && a.Logs.S3Buckets != nil {
for region := range a.Logs.S3Buckets {
if _, found := ValidAWSRegions[region]; !found {
return errors.NewInvalidInputf(CodeInvalidCloudRegion, "invalid cloud region: %s", region)
}
}
}
return nil
}
type PatchServiceConfigResponse struct {
ServiceId string `json:"id"`
Config any `json:"config"`
}
type PatchableAccountConfig struct {
OrgID string
AccountId string
Data []byte // can be either AWSAccountConfig
}
type PatchableAccountConfigTyped[T any] struct {
Config *T `json:"config"`
}
type PatchableAWSAccountConfig = PatchableAccountConfigTyped[AWSAccountConfig]
type AWSAccountConfig struct {
EnabledRegions []string `json:"regions"`
}
type GettableServices[T any] struct {
Services []T `json:"services"`
}
type GettableAWSServices = GettableServices[AWSServiceSummary]
type GetServiceDetailsReq struct {
OrgID valuer.UUID
ServiceId string
CloudAccountID *string
}
// --------------------------------------------------------------------------
// DATABASE TYPES
// --------------------------------------------------------------------------
// --------------------------------------------------------------------------
// Cloud integration uses the cloud_integration table
// and cloud_integrations_service table
// --------------------------------------------------------------------------
type CloudIntegration struct {
bun.BaseModel `bun:"table:cloud_integration"`
types.Identifiable
types.TimeAuditable
Provider string `json:"provider" bun:"provider,type:text,unique:provider_id"`
Config string `json:"config" bun:"config,type:text"` // json serialized config
AccountID *string `json:"account_id" bun:"account_id,type:text"`
LastAgentReport *AgentReport `json:"last_agent_report" bun:"last_agent_report,type:text"`
RemovedAt *time.Time `json:"removed_at" bun:"removed_at,type:timestamp,nullzero"`
OrgID string `bun:"org_id,type:text,unique:provider_id"`
}
func (a *CloudIntegration) Status() AccountStatus {
status := AccountStatus{}
if a.LastAgentReport != nil {
lastHeartbeat := a.LastAgentReport.TimestampMillis
status.Integration.LastHeartbeatTsMillis = &lastHeartbeat
}
return status
}
func (a *CloudIntegration) Account(cloudProvider CloudProviderType) *Account {
ca := &Account{Id: a.ID.StringValue(), Status: a.Status()}
if a.AccountID != nil {
ca.CloudAccountId = *a.AccountID
}
ca.Config = map[string]interface{}{}
if len(a.Config) < 1 {
return ca
}
switch cloudProvider {
case CloudProviderAWS:
config := new(AWSAccountConfig)
_ = UnmarshalJSON([]byte(a.Config), config)
ca.Config = config
default:
}
return ca
}
type Account struct {
Id string `json:"id"`
CloudAccountId string `json:"cloud_account_id"`
Config any `json:"config"` // AWSAccountConfig
Status AccountStatus `json:"status"`
}
type AccountStatus struct {
Integration AccountIntegrationStatus `json:"integration"`
}
type AccountIntegrationStatus struct {
LastHeartbeatTsMillis *int64 `json:"last_heartbeat_ts_ms"`
}
func DefaultAWSAccountConfig() AWSAccountConfig {
return AWSAccountConfig{
EnabledRegions: []string{},
}
}
type ServiceSummary[T any] struct {
DefinitionMetadata
Config *T `json:"config"`
}
type AWSServiceSummary = ServiceSummary[AWSCloudServiceConfig]
type GettableAWSServiceDetails struct {
AWSDefinition
Config *AWSCloudServiceConfig `json:"config"`
ConnectionStatus *ServiceConnectionStatus `json:"status,omitempty"`
}
type ServiceConnectionStatus struct {
Logs []*SignalConnectionStatus `json:"logs"`
Metrics []*SignalConnectionStatus `json:"metrics"`
}
type SignalConnectionStatus struct {
CategoryID string `json:"category"`
CategoryDisplayName string `json:"category_display_name"`
LastReceivedTsMillis int64 `json:"last_received_ts_ms"` // epoch milliseconds
LastReceivedFrom string `json:"last_received_from"` // resource identifier
}
type AgentReport struct {
TimestampMillis int64 `json:"timestamp_millis"`
Data map[string]any `json:"data"`
}
// Scan scans data from db
func (r *AgentReport) Scan(src any) error {
var data []byte
switch v := src.(type) {
case []byte:
data = v
case string:
data = []byte(v)
default:
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
}
return json.Unmarshal(data, r)
}
// Value serializes data to bytes for db insertion
func (r *AgentReport) Value() (driver.Value, error) {
if r == nil {
return nil, errors.NewInternalf(errors.CodeInternal, "agent report is nil")
}
serialized, err := json.Marshal(r)
if err != nil {
return nil, errors.WrapInternalf(
err, errors.CodeInternal, "couldn't serialize agent report to JSON",
)
}
return serialized, nil
}
type CloudIntegrationService struct {
bun.BaseModel `bun:"table:cloud_integration_service,alias:cis"`
types.Identifiable
types.TimeAuditable
Type string `bun:"type,type:text,notnull,unique:cloud_integration_id_type"`
Config string `bun:"config,type:text"` // json serialized config
CloudIntegrationID string `bun:"cloud_integration_id,type:text,notnull,unique:cloud_integration_id_type,references:cloud_integrations(id),on_delete:cascade"`
}
type AWSCloudServiceLogsConfig struct {
Enabled bool `json:"enabled"`
S3Buckets map[string][]string `json:"s3_buckets,omitempty"`
}
type AWSCloudServiceMetricsConfig struct {
Enabled bool `json:"enabled"`
}

View File

@@ -1,189 +0,0 @@
package integrationtypes
import (
"fmt"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/types/dashboardtypes"
"github.com/SigNoz/signoz/pkg/valuer"
)
const (
S3Sync = "s3sync"
)
type AWSDefinition = ServiceDefinition[AWSCollectionStrategy]
var _ Definition = &AWSDefinition{}
type ServiceDefinition[T any] struct {
DefinitionMetadata
Overview string `json:"overview"` // markdown
Assets Assets `json:"assets"`
SupportedSignals SupportedSignals `json:"supported_signals"`
DataCollected DataCollected `json:"data_collected"`
IngestionStatusCheck *IngestionStatusCheck `json:"ingestion_status_check,omitempty"`
Strategy *T `json:"telemetry_collection_strategy"`
}
func (def *ServiceDefinition[T]) PopulateDashboardURLs(cloudProvider CloudProviderType, svcId string) {
for i := range def.Assets.Dashboards {
dashboardId := def.Assets.Dashboards[i].Id
url := "/dashboard/" + GetCloudIntegrationDashboardID(cloudProvider, svcId, dashboardId)
def.Assets.Dashboards[i].Url = url
}
}
func (def *ServiceDefinition[T]) GetId() string {
return def.Id
}
func (def *ServiceDefinition[T]) Validate() error {
seenDashboardIds := map[string]interface{}{}
if def.Strategy == nil {
return errors.NewInternalf(errors.CodeInternal, "telemetry_collection_strategy is required")
}
for _, dd := range def.Assets.Dashboards {
if _, seen := seenDashboardIds[dd.Id]; seen {
return errors.NewInternalf(errors.CodeInternal, "multiple dashboards found with id %s", dd.Id)
}
seenDashboardIds[dd.Id] = nil
}
return nil
}
type DefinitionMetadata struct {
Id string `json:"id"`
Title string `json:"title"`
Icon string `json:"icon"`
}
type Definition interface {
GetId() string
Validate() error
PopulateDashboardURLs(cloudProvider CloudProviderType, svcId string)
}
type IngestionStatusCheck struct {
Metrics []*IngestionStatusCheckCategory `json:"metrics"`
Logs []*IngestionStatusCheckCategory `json:"logs"`
}
type IngestionStatusCheckCategory struct {
Category string `json:"category"`
DisplayName string `json:"display_name"`
Checks []*IngestionStatusCheckAttribute `json:"checks"`
}
type IngestionStatusCheckAttribute struct {
Key string `json:"key"` // search key (metric name or log message)
Attributes []*IngestionStatusCheckAttributeFilter `json:"attributes"`
}
type IngestionStatusCheckAttributeFilter struct {
Name string `json:"name"`
Operator string `json:"operator"`
Value string `json:"value"`
}
type Assets struct {
Dashboards []Dashboard `json:"dashboards"`
}
type SupportedSignals struct {
Logs bool `json:"logs"`
Metrics bool `json:"metrics"`
}
type DataCollected struct {
Logs []CollectedLogAttribute `json:"logs"`
Metrics []CollectedMetric `json:"metrics"`
}
type CollectedLogAttribute struct {
Name string `json:"name"`
Path string `json:"path"`
Type string `json:"type"`
}
type CollectedMetric struct {
Name string `json:"name"`
Type string `json:"type"`
Unit string `json:"unit"`
Description string `json:"description"`
}
type AWSCollectionStrategy struct {
Metrics *AWSMetricsStrategy `json:"aws_metrics,omitempty"`
Logs *AWSLogsStrategy `json:"aws_logs,omitempty"`
S3Buckets map[string][]string `json:"s3_buckets,omitempty"` // Only available in S3 Sync Service Type in AWS
}
type AWSMetricsStrategy struct {
// to be used as https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-cloudwatch-metricstream.html#cfn-cloudwatch-metricstream-includefilters
StreamFilters []struct {
// json tags here are in the shape expected by AWS API as detailed at
// https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudwatch-metricstream-metricstreamfilter.html
Namespace string `json:"Namespace"`
MetricNames []string `json:"MetricNames,omitempty"`
} `json:"cloudwatch_metric_stream_filters"`
}
type AWSLogsStrategy struct {
Subscriptions []struct {
// subscribe to all logs groups with specified prefix.
// eg: `/aws/rds/`
LogGroupNamePrefix string `json:"log_group_name_prefix"`
// https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/FilterAndPatternSyntax.html
// "" implies no filtering is required.
FilterPattern string `json:"filter_pattern"`
} `json:"cloudwatch_logs_subscriptions"`
}
type Dashboard struct {
Id string `json:"id"`
Url string `json:"url"`
Title string `json:"title"`
Description string `json:"description"`
Image string `json:"image"`
Definition *dashboardtypes.StorableDashboardData `json:"definition,omitempty"`
}
func GetCloudIntegrationDashboardID(cloudProvider valuer.String, svcId, dashboardId string) string {
return fmt.Sprintf("cloud-integration--%s--%s--%s", cloudProvider, svcId, dashboardId)
}
func GetDashboardsFromAssets(
svcId string,
orgID valuer.UUID,
cloudProvider CloudProviderType,
createdAt *time.Time,
assets Assets,
) []*dashboardtypes.Dashboard {
dashboards := make([]*dashboardtypes.Dashboard, 0)
for _, d := range assets.Dashboards {
author := fmt.Sprintf("%s-integration", cloudProvider)
dashboards = append(dashboards, &dashboardtypes.Dashboard{
ID: GetCloudIntegrationDashboardID(cloudProvider, svcId, d.Id),
Locked: true,
OrgID: orgID,
Data: *d.Definition,
TimeAuditable: types.TimeAuditable{
CreatedAt: *createdAt,
UpdatedAt: *createdAt,
},
UserAuditable: types.UserAuditable{
CreatedBy: author,
UpdatedBy: author,
},
})
}
return dashboards
}

View File

@@ -1,106 +0,0 @@
package integrationtypes
import (
"database/sql/driver"
"encoding/json"
"strings"
"time"
"github.com/SigNoz/signoz/pkg/errors"
"github.com/SigNoz/signoz/pkg/types"
"github.com/SigNoz/signoz/pkg/valuer"
"github.com/uptrace/bun"
)
// CloudProviderType type alias
type CloudProviderType = valuer.String
var (
CloudProviderAWS = valuer.NewString("aws")
)
var (
CodeCloudProviderInvalidInput = errors.MustNewCode("invalid_cloud_provider")
)
func NewCloudProvider(provider string) (CloudProviderType, error) {
switch provider {
case CloudProviderAWS.String():
return valuer.NewString(provider), nil
default:
return CloudProviderType{}, errors.NewInvalidInputf(CodeCloudProviderInvalidInput, "invalid cloud provider: %s", provider)
}
}
var (
AWSIntegrationUserEmail = valuer.MustNewEmail("aws-integration@signoz.io")
)
var IntegrationUserEmails = []valuer.Email{
AWSIntegrationUserEmail,
}
func IsCloudIntegrationDashboardUuid(dashboardUuid string) bool {
parts := strings.SplitN(dashboardUuid, "--", 4)
if len(parts) != 4 {
return false
}
return parts[0] == "cloud-integration"
}
func GetCloudProviderFromDashboardID(dashboardUuid string) (CloudProviderType, error) {
parts := strings.SplitN(dashboardUuid, "--", 4)
if len(parts) != 4 {
return valuer.String{}, errors.NewInvalidInputf(CodeCloudProviderInvalidInput, "invalid dashboard uuid: %s", dashboardUuid)
}
providerStr := parts[1]
cloudProvider, err := NewCloudProvider(providerStr)
if err != nil {
return CloudProviderType{}, err
}
return cloudProvider, nil
}
// --------------------------------------------------------------------------
// Normal integration uses just the installed_integration table
// --------------------------------------------------------------------------
type InstalledIntegration struct {
bun.BaseModel `bun:"table:installed_integration"`
types.Identifiable
Type string `json:"type" bun:"type,type:text,unique:org_id_type"`
Config InstalledIntegrationConfig `json:"config" bun:"config,type:text"`
InstalledAt time.Time `json:"installed_at" bun:"installed_at,default:current_timestamp"`
OrgID string `json:"org_id" bun:"org_id,type:text,unique:org_id_type,references:organizations(id),on_delete:cascade"`
}
type InstalledIntegrationConfig map[string]interface{}
// Scan scans data from db
func (c *InstalledIntegrationConfig) Scan(src interface{}) error {
var data []byte
switch v := src.(type) {
case []byte:
data = v
case string:
data = []byte(v)
default:
return errors.NewInternalf(errors.CodeInternal, "tried to scan from %T instead of string or bytes", src)
}
return json.Unmarshal(data, c)
}
// Value serializes data to db
func (c *InstalledIntegrationConfig) Value() (driver.Value, error) {
filterSetJson, err := json.Marshal(c)
if err != nil {
return nil, errors.WrapInternalf(err, errors.CodeInternal, "could not serialize integration config to JSON")
}
return filterSetJson, nil
}

View File

@@ -140,5 +140,5 @@ def test_generate_connection_url_unsupported_provider(
response_data = response.json()
assert "error" in response_data, "Response should contain 'error' field"
assert (
"invalid cloud provider: gcp" in response_data["error"]["message"]
"unsupported cloud provider" in response_data["error"].lower()
), "Error message should indicate unsupported provider"

View File

@@ -190,6 +190,7 @@ def test_get_service_details_with_account(
assert "overview" in data, "Service details should have 'overview' field"
assert "assets" in data, "Service details should have 'assets' field"
assert "config" in data, "Service details should have 'config' field"
assert "status" in data, "Config should have 'status' field"
def test_get_service_details_invalid_service(
@@ -345,8 +346,8 @@ def test_update_service_config_without_account(
)
assert (
response.status_code == HTTPStatus.NOT_FOUND
), f"Expected 400 for non-existent account, got {response.status_code}"
response.status_code == HTTPStatus.INTERNAL_SERVER_ERROR
), f"Expected 500 for non-existent account, got {response.status_code}"
def test_update_service_config_invalid_service(