141 lines
4.9 KiB
Go
141 lines
4.9 KiB
Go
package integration
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
integrationbiz "kra/internal/biz/integration"
|
|
"kra/internal/config"
|
|
|
|
"kra/internal/service/dto"
|
|
)
|
|
|
|
type IntegrationConfigService struct {
|
|
uc *integrationbiz.IntegrationConfigUsecase
|
|
}
|
|
|
|
func NewIntegrationConfigService(uc *integrationbiz.IntegrationConfigUsecase) *IntegrationConfigService {
|
|
return &IntegrationConfigService{uc: uc}
|
|
}
|
|
|
|
func (s *IntegrationConfigService) List(ctx context.Context, kind string) ([]*dto.IntegrationConfigResponse, error) {
|
|
configs, err := s.uc.List(ctx, kind)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
byProvider := make(map[string]*integrationbiz.IntegrationConfig, len(configs))
|
|
for _, config := range configs {
|
|
if config != nil {
|
|
byProvider[config.Provider] = config
|
|
}
|
|
}
|
|
definitions := integrationbiz.IntegrationDefinitions(kind)
|
|
result := make([]*dto.IntegrationConfigResponse, 0, len(definitions)+len(configs))
|
|
for _, definition := range definitions {
|
|
config, configured := byProvider[definition.Provider]
|
|
values := mergeConfigJSON(definition.Defaults, nil)
|
|
enabled := false
|
|
if configured {
|
|
values = mergeConfigJSON(definition.Defaults, config.Values)
|
|
enabled = config.Enabled
|
|
delete(byProvider, definition.Provider)
|
|
}
|
|
result = append(result, &dto.IntegrationConfigResponse{Kind: definition.Kind, Provider: definition.Provider, Name: definition.Name, Description: definition.Description, Enabled: enabled, Configured: configured, Config: redactIntegrationJSON(values), Fields: integrationFieldsDTO(definition.Fields)})
|
|
}
|
|
for _, config := range configs {
|
|
if _, exists := byProvider[config.Provider]; !exists {
|
|
continue
|
|
}
|
|
result = append(result, &dto.IntegrationConfigResponse{Kind: config.Kind, Provider: config.Provider, Name: config.Provider, Enabled: config.Enabled, Configured: true, Config: redactIntegrationJSON(config.Values)})
|
|
}
|
|
return result, nil
|
|
}
|
|
|
|
func (s *IntegrationConfigService) Find(ctx context.Context, kind, provider string) (*dto.IntegrationConfigResponse, error) {
|
|
config, err := s.uc.Find(ctx, kind, provider)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
definition, found := integrationbiz.IntegrationDefinition(config.Kind, config.Provider)
|
|
response := &dto.IntegrationConfigResponse{Kind: config.Kind, Provider: config.Provider, Name: config.Provider, Enabled: config.Enabled, Configured: true, Config: redactIntegrationJSON(config.Values)}
|
|
if found {
|
|
response.Name = definition.Name
|
|
response.Description = definition.Description
|
|
response.Fields = integrationFieldsDTO(definition.Fields)
|
|
response.Config = redactIntegrationJSON(mergeConfigJSON(definition.Defaults, config.Values))
|
|
}
|
|
return response, nil
|
|
}
|
|
|
|
func redactIntegrationJSON(raw json.RawMessage) json.RawMessage {
|
|
var value any
|
|
if json.Unmarshal(raw, &value) != nil {
|
|
return raw
|
|
}
|
|
var walk func(any)
|
|
walk = func(v any) {
|
|
switch x := v.(type) {
|
|
case map[string]any:
|
|
for k, item := range x {
|
|
if integrationbiz.IsIntegrationSecretKey(k) {
|
|
if text, ok := item.(string); ok && text != "" {
|
|
x[k] = config.MaskedSecret
|
|
}
|
|
} else {
|
|
walk(item)
|
|
}
|
|
}
|
|
case []any:
|
|
for _, item := range x {
|
|
walk(item)
|
|
}
|
|
}
|
|
}
|
|
walk(value)
|
|
out, _ := json.Marshal(value)
|
|
return out
|
|
}
|
|
|
|
func (s *IntegrationConfigService) Save(ctx context.Context, kind, provider string, req *dto.IntegrationConfigRequest) error {
|
|
if req == nil {
|
|
return s.uc.Save(ctx, nil)
|
|
}
|
|
return s.uc.Save(ctx, &integrationbiz.IntegrationConfig{Kind: kind, Provider: provider, Enabled: req.Enabled, Values: req.Config})
|
|
}
|
|
|
|
func (s *IntegrationConfigService) Test(ctx context.Context, kind, provider string, req *dto.IntegrationConfigRequest) error {
|
|
if req == nil {
|
|
return s.uc.Test(ctx, nil)
|
|
}
|
|
return s.uc.Test(ctx, &integrationbiz.IntegrationConfig{Kind: kind, Provider: provider, Enabled: true, Values: req.Config})
|
|
}
|
|
|
|
func (s *IntegrationConfigService) Delete(ctx context.Context, kind, provider string) error {
|
|
return s.uc.Delete(ctx, kind, provider)
|
|
}
|
|
|
|
func mergeConfigJSON(defaults map[string]any, raw json.RawMessage) json.RawMessage {
|
|
stored := map[string]any{}
|
|
_ = json.Unmarshal(raw, &stored)
|
|
values := integrationbiz.MergeIntegrationDefaults(defaults, stored)
|
|
encoded, _ := json.Marshal(values)
|
|
return encoded
|
|
}
|
|
|
|
func integrationFieldsDTO(fields []integrationbiz.IntegrationConfigField) []dto.IntegrationConfigField {
|
|
if fields == nil {
|
|
return nil
|
|
}
|
|
out := make([]dto.IntegrationConfigField, 0, len(fields))
|
|
for _, field := range fields {
|
|
item := dto.IntegrationConfigField{Key: field.Key, Label: field.Label, Type: field.Type, Required: field.Required, Secret: field.Secret, Placeholder: field.Placeholder, Description: field.Description}
|
|
if field.Options != nil {
|
|
item.Options = make([]dto.IntegrationConfigOption, 0, len(field.Options))
|
|
for _, option := range field.Options {
|
|
item.Options = append(item.Options, dto.IntegrationConfigOption{Label: option.Label, Value: option.Value})
|
|
}
|
|
}
|
|
out = append(out, item)
|
|
}
|
|
return out
|
|
}
|