@@ -11,6 +11,7 @@ import (
11
11
"github.com/flanksource/canary-checker/pkg/db"
12
12
pkgTopology "github.com/flanksource/canary-checker/pkg/topology"
13
13
"github.com/flanksource/commons/logger"
14
+ "github.com/flanksource/duty/models"
14
15
"github.com/flanksource/kommons"
15
16
"github.com/robfig/cron/v3"
16
17
"k8s.io/apimachinery/pkg/types"
@@ -71,7 +72,7 @@ func SyncTopologyJobs() {
71
72
72
73
func SyncTopologyJob (t v1.Topology ) error {
73
74
if ! t .DeletionTimestamp .IsZero () || t .Spec .GetSchedule () == "@never" {
74
- DeleteTopologyJob (t )
75
+ DeleteTopologyJob (t . GetPersistedID () )
75
76
return nil
76
77
}
77
78
if Kommons == nil {
@@ -81,7 +82,7 @@ func SyncTopologyJob(t v1.Topology) error {
81
82
logger .Warnf ("Failed to get kommons client, features that read kubernetes config will fail: %v" , err )
82
83
}
83
84
}
84
- entry := findTopologyCronEntry (t )
85
+ entry := findTopologyCronEntry (t . GetPersistedID () )
85
86
if entry != nil {
86
87
job := entry .Job .(TopologyJob )
87
88
if ! reflect .DeepEqual (job .Topology .Spec , t .Spec ) {
@@ -104,7 +105,7 @@ func SyncTopologyJob(t v1.Topology) error {
104
105
logger .Infof ("Scheduled %s/%s: %s" , t .Namespace , t .Name , t .Spec .GetSchedule ())
105
106
}
106
107
107
- entry = findTopologyCronEntry (t )
108
+ entry = findTopologyCronEntry (t . GetPersistedID () )
108
109
if entry != nil && time .Until (entry .Next ) < 1 * time .Hour {
109
110
// run all regular topologies on startup
110
111
job = entry .Job .(TopologyJob )
@@ -113,20 +114,55 @@ func SyncTopologyJob(t v1.Topology) error {
113
114
return nil
114
115
}
115
116
116
- func findTopologyCronEntry (t v1. Topology ) * cron.Entry {
117
+ func findTopologyCronEntry (id string ) * cron.Entry {
117
118
for _ , entry := range TopologyScheduler .Entries () {
118
- if entry .Job .(TopologyJob ).GetPersistedID () == t . GetPersistedID () {
119
+ if entry .Job .(TopologyJob ).GetPersistedID () == id {
119
120
return & entry
120
121
}
121
122
}
122
123
return nil
123
124
}
124
125
125
- func DeleteTopologyJob (t v1. Topology ) {
126
- entry := findTopologyCronEntry (t )
126
+ func DeleteTopologyJob (id string ) {
127
+ entry := findTopologyCronEntry (id )
127
128
if entry == nil {
128
129
return
129
130
}
130
- logger .Tracef ("deleting cron entry for topology %s/%s with entry ID: %v" , t . Name , t . Namespace , entry .ID )
131
+ logger .Tracef ("deleting cron entry for topology:%s with entry ID: %v" , id , entry .ID )
131
132
TopologyScheduler .Remove (entry .ID )
132
133
}
134
+
135
+ func ReconcileDeletedTopologyComponents () {
136
+ jobHistory := models .NewJobHistory ("ReconcileDeletedTopologyComponents" , "" , "" ).Start ()
137
+ _ = db .PersistJobHistory (jobHistory )
138
+ defer func () { _ = db .PersistJobHistory (jobHistory .End ()) }()
139
+
140
+ var rows []struct {
141
+ ID string
142
+ DeletedAt time.Time
143
+ }
144
+ // Select all components whose topology ID is deleted but their deleted at is not marked
145
+ err := db .Gorm .Raw (`
146
+ SELECT DISTINCT(topologies.id), topologies.deleted_at as deleted_at
147
+ FROM topologies
148
+ INNER JOIN components ON topologies.id = components.topology_id
149
+ WHERE
150
+ components.deleted_at IS NULL AND
151
+ topologies.deleted_at IS NOT NULL
152
+ ` ).Scan (& rows ).Error
153
+
154
+ if err != nil {
155
+ logger .Errorf ("Error fetching deleted topology components: %v" , err )
156
+ jobHistory .AddError (err .Error ())
157
+ return
158
+ }
159
+
160
+ for _ , r := range rows {
161
+ if err := db .DeleteComponentsOfTopology (r .ID , r .DeletedAt ); err != nil {
162
+ logger .Errorf ("Error deleting components for topology[%s]: %v" , r .ID , err )
163
+ jobHistory .AddError (err .Error ())
164
+ }
165
+ DeleteTopologyJob (r .ID )
166
+ }
167
+ jobHistory .IncrSuccess ()
168
+ }
0 commit comments