mirror of
https://github.com/SigNoz/signoz.git
synced 2026-05-28 12:50:32 +01:00
Some checks failed
build-staging / prepare (push) Has been cancelled
Release Drafter / update_release_draft (push) Has been cancelled
build-staging / go-build (push) Has been cancelled
build-staging / staging (push) Has been cancelled
build-staging / js-build (push) Has been cancelled
* chore: added migration setup * feat(sqlmigration): add integration_dashboards table (migration 079) Adds the `integration_dashboards` relations table that stores the integration-specific identity for dashboards provisioned from cloud or builtin integrations. Columns: id, org_id, dashboard_id, provider, slug, created_at, updated_at. Includes a unique index on dashboard_id. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * feat(sqlmigration): backfill cloud integration dashboards to DB (migration 080) One-time idempotent migration that provisions dashboard rows for all orgs with existing cloud integration services where metrics are enabled. Each dashboard is inserted into the `dashboard` table with source="integration" and locked=true, and a companion row is added to `integration_dashboards` with provider="cloud_integrations" and slug="{provider}-{service}-{dashboard}" (e.g. aws-alb-overview). Idempotency is enforced by checking (org_id, provider, slug) on integration_dashboards before each insert. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore(sqlmigration): clean up stale 079 artifacts, add 079 schema migration Remove the pre-rename 079_migrate_cloud_integration_dashboards.go and 079_cloud_integration_dashboards/ directory that were left behind when the backfill migration was renumbered to 080. Add the missing 079_add_integration_dashboards.go (schema-only migration creating the integration_dashboards table) which provider.go already references. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> * chore: adding comment for fk * refactor: renaming table name * refactor: rename and restructure cloud integration dashboard migration types * chore: file rename * refactor: dashboard creation and listing flow change * refactor: removing loose strings * refactor: adding DeleteBySource on dashboard module * refactor: review changes and update service flow change * refactor: simplify comments * ci: lint staticcheck fix * refactor: renaming migration and adding integration tests * ci: py fmt lint fixes * feat: adding ListSharedServices store method * ci: golangci-lint fix * refactor: code cleanup * chore: revert changed due to js lint * refactor: test assertion changes * refactor: using bindparam for sql generation * chore: migrate integration dashboards json to v5 (#11419) --------- Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com> Co-authored-by: Srikanth Chekuri <srikanth.chekuri92@gmail.com>
124 lines
4.7 KiB
Go
124 lines
4.7 KiB
Go
package implcloudprovider
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"net/url"
|
|
"sort"
|
|
|
|
"github.com/SigNoz/signoz/pkg/modules/cloudintegration"
|
|
"github.com/SigNoz/signoz/pkg/types/cloudintegrationtypes"
|
|
)
|
|
|
|
type awscloudprovider struct {
|
|
serviceDefinitions cloudintegrationtypes.ServiceDefinitionStore
|
|
}
|
|
|
|
func NewAWSCloudProvider(defStore cloudintegrationtypes.ServiceDefinitionStore) (cloudintegration.CloudProviderModule, error) {
|
|
return &awscloudprovider{serviceDefinitions: defStore}, nil
|
|
}
|
|
|
|
// TODO: move URL construction logic to cloudintegrationtypes and add unit tests for it.
|
|
func (provider *awscloudprovider) GetConnectionArtifact(ctx context.Context, account *cloudintegrationtypes.Account, req *cloudintegrationtypes.GetConnectionArtifactRequest) (*cloudintegrationtypes.ConnectionArtifact, error) {
|
|
baseURL := fmt.Sprintf(cloudintegrationtypes.CloudFormationQuickCreateBaseURL.StringValue(), req.Config.AWS.DeploymentRegion)
|
|
u, _ := url.Parse(baseURL)
|
|
|
|
q := u.Query()
|
|
q.Set("region", req.Config.AWS.DeploymentRegion)
|
|
u.Fragment = "/stacks/quickcreate"
|
|
|
|
u.RawQuery = q.Encode()
|
|
|
|
q = u.Query()
|
|
q.Set("stackName", cloudintegrationtypes.AgentCloudFormationBaseStackName.StringValue())
|
|
q.Set("templateURL", fmt.Sprintf(cloudintegrationtypes.AgentCloudFormationTemplateS3Path.StringValue(), req.Config.AgentVersion))
|
|
q.Set("param_SigNozIntegrationAgentVersion", req.Config.AgentVersion)
|
|
q.Set("param_SigNozApiUrl", req.Credentials.SigNozAPIURL)
|
|
q.Set("param_SigNozApiKey", req.Credentials.SigNozAPIKey)
|
|
q.Set("param_SigNozAccountId", account.ID.StringValue())
|
|
q.Set("param_IngestionUrl", req.Credentials.IngestionURL)
|
|
q.Set("param_IngestionKey", req.Credentials.IngestionKey)
|
|
|
|
return &cloudintegrationtypes.ConnectionArtifact{
|
|
AWS: cloudintegrationtypes.NewAWSConnectionArtifact(u.String() + "?&" + q.Encode()), // this format is required by AWS
|
|
}, nil
|
|
}
|
|
|
|
func (provider *awscloudprovider) ListServiceDefinitions(ctx context.Context) ([]*cloudintegrationtypes.ServiceDefinition, error) {
|
|
return provider.serviceDefinitions.List(ctx, cloudintegrationtypes.CloudProviderTypeAWS)
|
|
}
|
|
|
|
func (provider *awscloudprovider) GetServiceDefinition(ctx context.Context, serviceID cloudintegrationtypes.ServiceID) (*cloudintegrationtypes.ServiceDefinition, error) {
|
|
serviceDef, err := provider.serviceDefinitions.Get(ctx, cloudintegrationtypes.CloudProviderTypeAWS, serviceID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return serviceDef, nil
|
|
}
|
|
|
|
func (provider *awscloudprovider) BuildIntegrationConfig(
|
|
ctx context.Context,
|
|
account *cloudintegrationtypes.Account,
|
|
services []*cloudintegrationtypes.StorableCloudIntegrationService,
|
|
) (*cloudintegrationtypes.ProviderIntegrationConfig, error) {
|
|
// Sort services for deterministic output
|
|
sort.Slice(services, func(i, j int) bool {
|
|
return services[i].Type.StringValue() < services[j].Type.StringValue()
|
|
})
|
|
|
|
compiledMetrics := new(cloudintegrationtypes.AWSMetricsCollectionStrategy)
|
|
compiledLogs := new(cloudintegrationtypes.AWSLogsCollectionStrategy)
|
|
var compiledS3Buckets map[string][]string
|
|
|
|
for _, storedSvc := range services {
|
|
svcCfg, err := cloudintegrationtypes.NewServiceConfigFromJSON(cloudintegrationtypes.CloudProviderTypeAWS, storedSvc.Config)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
svcDef, err := provider.GetServiceDefinition(ctx, storedSvc.Type)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
strategy := svcDef.TelemetryCollectionStrategy.AWS
|
|
logsEnabled := svcCfg.IsLogsEnabled(cloudintegrationtypes.CloudProviderTypeAWS)
|
|
|
|
// S3Sync: logs come directly from configured S3 buckets, not CloudWatch subscriptions
|
|
if storedSvc.Type == cloudintegrationtypes.AWSServiceS3Sync {
|
|
if logsEnabled && svcCfg.AWS.Logs.S3Buckets != nil {
|
|
compiledS3Buckets = svcCfg.AWS.Logs.S3Buckets
|
|
}
|
|
// no need to go ahead as the code block specifically checks for the S3Sync service
|
|
continue
|
|
}
|
|
|
|
if logsEnabled && strategy.Logs != nil {
|
|
compiledLogs.Subscriptions = append(compiledLogs.Subscriptions, strategy.Logs.Subscriptions...)
|
|
}
|
|
|
|
metricsEnabled := svcCfg.IsMetricsEnabled(cloudintegrationtypes.CloudProviderTypeAWS)
|
|
|
|
if metricsEnabled && strategy.Metrics != nil {
|
|
compiledMetrics.StreamFilters = append(compiledMetrics.StreamFilters, strategy.Metrics.StreamFilters...)
|
|
}
|
|
}
|
|
|
|
collectionStrategy := new(cloudintegrationtypes.AWSTelemetryCollectionStrategy)
|
|
|
|
if len(compiledMetrics.StreamFilters) > 0 {
|
|
collectionStrategy.Metrics = compiledMetrics
|
|
}
|
|
if len(compiledLogs.Subscriptions) > 0 {
|
|
collectionStrategy.Logs = compiledLogs
|
|
}
|
|
if compiledS3Buckets != nil {
|
|
collectionStrategy.S3Buckets = compiledS3Buckets
|
|
}
|
|
|
|
return &cloudintegrationtypes.ProviderIntegrationConfig{
|
|
AWS: cloudintegrationtypes.NewAWSIntegrationConfig(account.Config.AWS.Regions, collectionStrategy),
|
|
}, nil
|
|
}
|