mirror of
https://git.mirrors.martin98.com/https://github.com/SigNoz/signoz
synced 2025-07-30 23:52:00 +08:00

* feat: init app/cloud_integrations * feat: get API test started for cloudintegrations account lifecycle * feat: cloudintegrations: get controller started * feat: cloud integrations: add cloudintegrations.Controller to APIHandler and servers * feat: cloud integrations: get routes started * feat: cloud integrations: get accounts table schema started * feat: cloud integrations: get cloudProviderAccountsSQLRepository started * feat: cloud integrations: cloudProviderAccountsSQLRepository.listAccounts * feat: cloud integrations: http handler and controller plumbing for /generate-connection-url * feat: cloud integrations: cloudProviderAccountsSQLRepository.upsert * feat: cloud integrations: finish up with /generate-connection-url * feat: cloud integrations: add cloudProviderAccountsRepository.get * feat: cloud integrations: add API test expectation for being able to get account status * feat: cloud integrations: add http handler and controller method for getting account status * feat: cloud integrations: ensure unconnected accounts aren't included in list of connected accounts * feat: cloud integrations: add test expectation for agent check in request * feat: cloud integrations: agent check in API * feat: cloud integrations: ensure polling for status after agent check in works * feat: cloud integrations: ensure account included in connected account list after agent check in * feat: cloud integrations: add API expectation for updating account config * feat: cloud integrations: API for updating cloud account config * feat: cloud integrations: expectation for agent receiving latest config after account config update * feat: cloud integrations: expectation for disconnecting cloud accounts from UI * feat: cloud integrations: API for disconnecting cloud accounts * feat: cloud integrations: some cleanup * feat: cloud integrations: some more cleanup * feat: cloud integrations: repo: scope rows by cloud provider * feat: testutils: refactor out helper for creating a test sqlite DB * feat: cloud integrations: controller: add test validating regeneration of connection url * feat: cloud integrations: controller: validations for agent check ins * feat: cloud integrations: connected account response structure * feat: cloud integrations: API response account structure * feat: cloud integrations: some more cleanup * feat: cloud integrations: remove cloudProviderAccountsRepository.GetById * feat: cloud integrations: shouldn't be able to disconnect non-existent account * feat: cloud integrations: validate agents can't check in to cloud account with 2 signoz ids * feat: cloud integrations: ensure agents can't check in to cloud account with 2 signoz ids * feat: cloud integrations: remove stray import of ee/model in cloudintegrations controller
118 lines
2.6 KiB
Go
118 lines
2.6 KiB
Go
package cloudintegrations
|
|
|
|
import (
|
|
"database/sql/driver"
|
|
"encoding/json"
|
|
"fmt"
|
|
"time"
|
|
)
|
|
|
|
// Represents a cloud provider account for cloud integrations
|
|
type AccountRecord struct {
|
|
CloudProvider string `json:"cloud_provider" db:"cloud_provider"`
|
|
Id string `json:"id" db:"id"`
|
|
Config *AccountConfig `json:"config" db:"config_json"`
|
|
CloudAccountId *string `json:"cloud_account_id" db:"cloud_account_id"`
|
|
LastAgentReport *AgentReport `json:"last_agent_report" db:"last_agent_report_json"`
|
|
CreatedAt time.Time `json:"created_at" db:"created_at"`
|
|
RemovedAt *time.Time `json:"removed_at" db:"removed_at"`
|
|
}
|
|
|
|
type AccountConfig struct {
|
|
EnabledRegions []string `json:"regions"`
|
|
}
|
|
|
|
func DefaultAccountConfig() AccountConfig {
|
|
return AccountConfig{
|
|
EnabledRegions: []string{},
|
|
}
|
|
}
|
|
|
|
// For serializing from db
|
|
func (c *AccountConfig) Scan(src any) error {
|
|
data, ok := src.([]byte)
|
|
if !ok {
|
|
return fmt.Errorf("tried to scan from %T instead of bytes", src)
|
|
}
|
|
|
|
return json.Unmarshal(data, &c)
|
|
}
|
|
|
|
// For serializing to db
|
|
func (c *AccountConfig) Value() (driver.Value, error) {
|
|
if c == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
serialized, err := json.Marshal(c)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"couldn't serialize cloud account config to JSON: %w", err,
|
|
)
|
|
}
|
|
return 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 {
|
|
data, ok := src.([]byte)
|
|
if !ok {
|
|
return fmt.Errorf("tried to scan from %T instead of bytes", src)
|
|
}
|
|
|
|
return json.Unmarshal(data, &r)
|
|
}
|
|
|
|
// For serializing to db
|
|
func (r *AgentReport) Value() (driver.Value, error) {
|
|
if r == nil {
|
|
return nil, nil
|
|
}
|
|
|
|
serialized, err := json.Marshal(r)
|
|
if err != nil {
|
|
return nil, fmt.Errorf(
|
|
"couldn't serialize agent report to JSON: %w", err,
|
|
)
|
|
}
|
|
return serialized, nil
|
|
}
|
|
|
|
type AccountStatus struct {
|
|
Integration AccountIntegrationStatus `json:"integration"`
|
|
}
|
|
|
|
type AccountIntegrationStatus struct {
|
|
LastHeartbeatTsMillis *int64 `json:"last_heartbeat_ts_ms"`
|
|
}
|
|
|
|
func (a *AccountRecord) status() AccountStatus {
|
|
status := AccountStatus{}
|
|
if a.LastAgentReport != nil {
|
|
lastHeartbeat := a.LastAgentReport.TimestampMillis
|
|
status.Integration.LastHeartbeatTsMillis = &lastHeartbeat
|
|
}
|
|
return status
|
|
}
|
|
|
|
func (a *AccountRecord) account() Account {
|
|
ca := Account{Id: a.Id, Status: a.status()}
|
|
|
|
if a.CloudAccountId != nil {
|
|
ca.CloudAccountId = *a.CloudAccountId
|
|
}
|
|
|
|
if a.Config != nil {
|
|
ca.Config = *a.Config
|
|
} else {
|
|
ca.Config = DefaultAccountConfig()
|
|
}
|
|
|
|
return ca
|
|
}
|