feat(cloudflare): add custom targets and node failover (#43)

* feat(cloudflare): add custom targets and node failover

* fix(cloudflare): propagate batch sync errors

---------

Co-authored-by: OpenAI Codex <codex@openai.com>
This commit is contained in:
Ryan
2026-10-07 11:29:41 +08:00
committed by GitHub
parent e49e0ad2bf
commit fd0e9acc2f
28 changed files with 1144 additions and 155 deletions
+20 -3
View File
@@ -64,6 +64,11 @@ func ListCFPointingGroups(ctx context.Context) ([]model.CFPointingGroup, error)
return items, nil
}
// UpdateCFPointingGroupTarget updates the active node or custom-record target.
func UpdateCFPointingGroupTarget(ctx context.Context, groupID uint, changes map[string]any) error {
return db.DB(ctx).Model(&model.CFPointingGroup{}).Where("id = ?", groupID).Updates(changes).Error
}
// GetCFPointingGroup returns a group by ID.
func GetCFPointingGroup(ctx context.Context, id uint) (*model.CFPointingGroup, error) {
var item model.CFPointingGroup
@@ -192,9 +197,12 @@ func GetCFPointingMemberContext(ctx context.Context, memberID uint) (*CFPointing
if err != nil {
return nil, err
}
node, err := GetOpenFlareNodeByID(ctx, group.ActiveNodeID)
if err != nil {
return nil, err
node := &model.OpenFlareNode{}
if group.TargetMode != model.CFPointingTargetModeCustom {
node, err = GetOpenFlareNodeByID(ctx, group.ActiveNodeID)
if err != nil {
return nil, err
}
}
return &CFPointingMemberContext{Member: *member, Group: *group, Domain: *domain, Zone: *zone, Node: *node}, nil
}
@@ -214,6 +222,15 @@ func MarkCFPointingGroupMembersPending(ctx context.Context, groupID uint) error
Updates(map[string]any{"sync_status": model.CFMemberSyncPending, "last_error": ""}).Error
}
// HasPendingCFPointingGroupMembers reports whether a group has members awaiting reconciliation.
func HasPendingCFPointingGroupMembers(ctx context.Context, groupID uint) (bool, error) {
var count int64
err := db.DB(ctx).Model(&model.CFPointingMember{}).
Where("group_id = ? AND sync_status = ?", groupID, model.CFMemberSyncPending).
Count(&count).Error
return count > 0, err
}
// DeleteCFPointingGroupAndMembers removes a group after its remote records are deleted.
func DeleteCFPointingGroupAndMembers(ctx context.Context, groupID uint) error {
return db.DB(ctx).Transaction(func(tx *gorm.DB) error {