go-duck-cli 1.1.18 → 1.1.20
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/generators/devops.js +9 -4
- package/generators/multitenancy.js +25 -5
- package/package.json +1 -1
- package/templates/go/router.go.hbs +28 -0
package/generators/devops.js
CHANGED
|
@@ -96,6 +96,11 @@ services:
|
|
|
96
96
|
- "${dbPort}:5432"
|
|
97
97
|
volumes:
|
|
98
98
|
- postgres_data:/var/lib/postgresql/data
|
|
99
|
+
healthcheck:
|
|
100
|
+
test: ["CMD-SHELL", "pg_isready -U ${config.datasource?.username || 'postgres'} -d ${config.datasource?.database || 'go_duck_master'}"]
|
|
101
|
+
interval: 5s
|
|
102
|
+
timeout: 5s
|
|
103
|
+
retries: 5
|
|
99
104
|
networks:
|
|
100
105
|
- go-duck-net
|
|
101
106
|
|
|
@@ -166,7 +171,8 @@ services:
|
|
|
166
171
|
KC_DB_USERNAME: ${config.datasource?.username || 'postgres'}
|
|
167
172
|
KC_DB_PASSWORD: ${config.datasource?.password || 'password'}
|
|
168
173
|
depends_on:
|
|
169
|
-
|
|
174
|
+
postgres:
|
|
175
|
+
condition: service_healthy
|
|
170
176
|
volumes:
|
|
171
177
|
- ./keycloak/realm-config:/opt/keycloak/data/import
|
|
172
178
|
ports:
|
|
@@ -240,7 +246,7 @@ services:
|
|
|
240
246
|
- GO_DUCK_ELASTICSEARCH_ADDRESSES=http://elasticsearch:9200
|
|
241
247
|
depends_on:
|
|
242
248
|
postgres:
|
|
243
|
-
condition:
|
|
249
|
+
condition: service_healthy
|
|
244
250
|
redis:
|
|
245
251
|
condition: service_started
|
|
246
252
|
mosquitto:
|
|
@@ -254,8 +260,7 @@ services:
|
|
|
254
260
|
|
|
255
261
|
networks:
|
|
256
262
|
go-duck-net:
|
|
257
|
-
|
|
258
|
-
name: devops_go-duck-net
|
|
263
|
+
driver: bridge
|
|
259
264
|
`;
|
|
260
265
|
|
|
261
266
|
// --- 5. MQTT Broker Config ---
|
|
@@ -179,12 +179,22 @@ func TenantMiddleware(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
|
|
179
179
|
}
|
|
180
180
|
|
|
181
181
|
if len(mappings) == 0 {
|
|
182
|
-
conn,
|
|
182
|
+
conn, err := mgr.GetDB(fallbackDB)
|
|
183
|
+
if err != nil || conn == nil {
|
|
184
|
+
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to resolve tenant fallback database connection"})
|
|
185
|
+
c.Abort()
|
|
186
|
+
return
|
|
187
|
+
}
|
|
183
188
|
siloConnections["fallback"] = conn
|
|
184
189
|
c.Set("tenantDBConn", conn)
|
|
185
190
|
|
|
186
191
|
if cfg.GoDuck.Datasource.MongoDB.Enabled {
|
|
187
|
-
mClient,
|
|
192
|
+
mClient, err := mgr.GetMongoClient(fallbackDB)
|
|
193
|
+
if err != nil || mClient == nil {
|
|
194
|
+
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to resolve tenant fallback MongoDB connection"})
|
|
195
|
+
c.Abort()
|
|
196
|
+
return
|
|
197
|
+
}
|
|
188
198
|
mDB := mClient.Database(fallbackDB)
|
|
189
199
|
mongoConnections["fallback"] = mDB
|
|
190
200
|
c.Set("tenantMongoDB", mDB)
|
|
@@ -214,11 +224,21 @@ func TenantMiddleware(db *gorm.DB, cfg *config.Config) gin.HandlerFunc {
|
|
|
214
224
|
|
|
215
225
|
// The FIRST one in our sorted list is the primary/lead silo for this request
|
|
216
226
|
if len(mappings) > 0 {
|
|
217
|
-
primaryConn,
|
|
227
|
+
primaryConn, err := mgr.GetDB(mappings[0].DBName)
|
|
228
|
+
if err != nil || primaryConn == nil {
|
|
229
|
+
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to resolve primary tenant database connection"})
|
|
230
|
+
c.Abort()
|
|
231
|
+
return
|
|
232
|
+
}
|
|
218
233
|
c.Set("tenantDBConn", primaryConn)
|
|
219
234
|
|
|
220
235
|
if cfg.GoDuck.Datasource.MongoDB.Enabled {
|
|
221
|
-
mClient,
|
|
236
|
+
mClient, err := mgr.GetMongoClient(mappings[0].DBName)
|
|
237
|
+
if err != nil || mClient == nil {
|
|
238
|
+
c.JSON(http.StatusInternalServerError, gin.H{"error": "Failed to resolve primary tenant MongoDB connection"})
|
|
239
|
+
c.Abort()
|
|
240
|
+
return
|
|
241
|
+
}
|
|
222
242
|
c.Set("tenantMongoDB", mClient.Database(mappings[0].DBName))
|
|
223
243
|
}
|
|
224
244
|
|
|
@@ -309,7 +329,7 @@ func CreateDatabaseAndMigrate(masterDB *gorm.DB) gin.HandlerFunc {
|
|
|
309
329
|
var exists int
|
|
310
330
|
masterDB.Raw("SELECT 1 FROM pg_database WHERE datname = ?", req.DBName).Scan(&exists)
|
|
311
331
|
if exists == 0 {
|
|
312
|
-
masterDB.Exec(fmt.Sprintf("CREATE DATABASE %s", req.DBName))
|
|
332
|
+
masterDB.Exec(fmt.Sprintf("CREATE DATABASE \"%s\"", req.DBName))
|
|
313
333
|
}
|
|
314
334
|
|
|
315
335
|
// 2. Clear other primary flags for this role if setting new primary
|
package/package.json
CHANGED
|
@@ -2,8 +2,10 @@ package router
|
|
|
2
2
|
|
|
3
3
|
import (
|
|
4
4
|
"context"
|
|
5
|
+
"fmt"
|
|
5
6
|
"log"
|
|
6
7
|
"net/http"
|
|
8
|
+
"strings"
|
|
7
9
|
"time"
|
|
8
10
|
|
|
9
11
|
"github.com/gin-gonic/gin"
|
|
@@ -84,6 +86,32 @@ func SetupRouter(appConfig *config.Config) *gin.Engine {
|
|
|
84
86
|
if err := migrations.RunGoNativeMigrations(masterDB); err != nil {
|
|
85
87
|
logger.Error("Goose Migration failed: %v", err)
|
|
86
88
|
}
|
|
89
|
+
|
|
90
|
+
// 10b. Initialize and Migrate Fallback DB if multi-tenancy is enabled
|
|
91
|
+
if appConfig.GoDuck.Multitenancy.Enabled {
|
|
92
|
+
fallbackDB := strings.ToLower(appConfig.GoDuck.Name) + "_fallback"
|
|
93
|
+
var exists int
|
|
94
|
+
masterDB.Raw("SELECT 1 FROM pg_database WHERE datname = ?", fallbackDB).Scan(&exists)
|
|
95
|
+
if exists == 0 {
|
|
96
|
+
if err := masterDB.Exec(fmt.Sprintf("CREATE DATABASE \"%s\"", fallbackDB)).Error; err != nil {
|
|
97
|
+
log.Printf("Warning: Failed to create fallback database %s: %v", fallbackDB, err)
|
|
98
|
+
} else {
|
|
99
|
+
log.Printf("✅ Created fallback database: %s", fallbackDB)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Run tenant migrations on the fallback database
|
|
104
|
+
mgr := middleware.GetTenantManager(masterDB, appConfig)
|
|
105
|
+
if fDB, err := mgr.GetDB(fallbackDB); err == nil {
|
|
106
|
+
if err := migrations.RunGoNativeMigrationsForTenant(fDB); err != nil {
|
|
107
|
+
log.Printf("Warning: Failed to run migrations on fallback database: %v", err)
|
|
108
|
+
} else {
|
|
109
|
+
log.Printf("✅ Migrated fallback database: %s", fallbackDB)
|
|
110
|
+
}
|
|
111
|
+
} else {
|
|
112
|
+
log.Printf("Warning: Failed to connect to fallback database for migration: %v", err)
|
|
113
|
+
}
|
|
114
|
+
}
|
|
87
115
|
}
|
|
88
116
|
|
|
89
117
|
var masterMongo *mongo.Client
|