Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 33 additions & 4 deletions controller/deployment.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package controller

import (
"bytes"
"encoding/json"
"fmt"
"strconv"
"strings"
Expand All @@ -23,6 +25,20 @@ func getIoAPIKey(c *gin.Context) (string, bool) {
return apiKey, true
}

func GetModelDeploymentSettings(c *gin.Context) {
common.OptionMapRWMutex.RLock()
enabled := common.OptionMap["model_deployment.ionet.enabled"] == "true"
hasAPIKey := strings.TrimSpace(common.OptionMap["model_deployment.ionet.api_key"]) != ""
common.OptionMapRWMutex.RUnlock()

common.ApiSuccess(c, gin.H{
"provider": "io.net",
"enabled": enabled,
"configured": hasAPIKey,
"can_connect": enabled && hasAPIKey,
})
}

func getIoClient(c *gin.Context) (*ionet.Client, bool) {
apiKey, ok := getIoAPIKey(c)
if !ok {
Expand All @@ -44,15 +60,28 @@ func TestIoNetConnection(c *gin.Context) {
APIKey string `json:"api_key"`
}

if err := c.ShouldBindJSON(&req); err != nil {
common.ApiErrorMsg(c, "invalid request payload")
rawBody, err := c.GetRawData()
if err != nil {
common.ApiError(c, err)
return
}
if len(bytes.TrimSpace(rawBody)) > 0 {
if err := json.Unmarshal(rawBody, &req); err != nil {
common.ApiErrorMsg(c, "invalid request payload")
return
}
}

apiKey := strings.TrimSpace(req.APIKey)
if apiKey == "" {
common.ApiErrorMsg(c, "api_key is required")
return
common.OptionMapRWMutex.RLock()
storedKey := strings.TrimSpace(common.OptionMap["model_deployment.ionet.api_key"])
common.OptionMapRWMutex.RUnlock()
if storedKey == "" {
common.ApiErrorMsg(c, "api_key is required")
return
}
apiKey = storedKey
}

client := ionet.NewEnterpriseClient(apiKey)
Expand Down
6 changes: 5 additions & 1 deletion controller/option.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,11 @@ func GetOptions(c *gin.Context) {
var options []*model.Option
common.OptionMapRWMutex.Lock()
for k, v := range common.OptionMap {
if strings.HasSuffix(k, "Token") || strings.HasSuffix(k, "Secret") || strings.HasSuffix(k, "Key") {
if strings.HasSuffix(k, "Token") ||
strings.HasSuffix(k, "Secret") ||
strings.HasSuffix(k, "Key") ||
strings.HasSuffix(k, "secret") ||
strings.HasSuffix(k, "api_key") {
continue
}
options = append(options, &model.Option{
Expand Down
18 changes: 2 additions & 16 deletions router/api-router.go
Original file line number Diff line number Diff line change
Expand Up @@ -269,24 +269,18 @@ func SetApiRouter(router *gin.Engine) {
deploymentsRoute := apiRouter.Group("/deployments")
deploymentsRoute.Use(middleware.AdminAuth())
{
// List and search deployments
deploymentsRoute.GET("/settings", controller.GetModelDeploymentSettings)
deploymentsRoute.POST("/settings/test-connection", controller.TestIoNetConnection)
deploymentsRoute.GET("/", controller.GetAllDeployments)
deploymentsRoute.GET("/search", controller.SearchDeployments)

// Connection utilities
deploymentsRoute.POST("/test-connection", controller.TestIoNetConnection)
Comment on lines +272 to 276

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, let's see the exact file and lines in question
cd / && find . -name "api-router.go" -type f 2>/dev/null | head -5

Repository: QuantumNous/new-api

Length of output: 103


🏁 Script executed:

# Read the router file around the specified lines
cat -n router/api-router.go | sed -n '260,280p'

Repository: QuantumNous/new-api

Length of output: 1329


🏁 Script executed:

# Search for all references to "test-connection" in the codebase
rg -n "test-connection" --type-list | head -20

Repository: QuantumNous/new-api

Length of output: 452


🏁 Script executed:

# Search for frontend/UI usage of test-connection endpoints
rg -rn "test-connection" --type=js --type=jsx --type=ts --type=tsx

Repository: QuantumNous/new-api

Length of output: 90


🏁 Script executed:

# Check the controller implementation to see if handlers differ
rg -n "TestIoNetConnection" router/api-router.go -B 2 -A 2

Repository: QuantumNous/new-api

Length of output: 596


🏁 Script executed:

# Search for any usage of /deployments/test-connection vs /deployments/settings/test-connection
rg -n "deployments.*test-connection|test-connection.*deployments" -i

Repository: QuantumNous/new-api

Length of output: 504


🏁 Script executed:

# Search for any usages of just "test-connection" without "settings/"
rg -n "test-connection" --type=go -A 2 -B 2

Repository: QuantumNous/new-api

Length of output: 764


🏁 Script executed:

# Search in test files for any references to /test-connection
find . -name "*test*.go" -o -name "*_test.go" | xargs rg "test-connection" 2>/dev/null

Repository: QuantumNous/new-api

Length of output: 47


🏁 Script executed:

# Check if there's any documentation or comments about the old endpoint
rg -n "test-connection" --type=md --type=txt

Repository: QuantumNous/new-api

Length of output: 45


Remove unused duplicate endpoint at line 272.

The POST /test-connection endpoint at line 272 duplicates functionality from the newer POST /settings/test-connection endpoint (line 269). Frontend code uses only the /settings/test-connection variant; the plain /test-connection endpoint appears to be dead code. Remove line 272 to eliminate unnecessary API surface duplication.

🤖 Prompt for AI Agents
In router/api-router.go around lines 268 to 272, remove the duplicate dead route
declaration at line 272 that registers deploymentsRoute.POST("/test-connection",
controller.TestIoNetConnection); keep the newer POST /settings/test-connection
route (line 269) and delete the plain /test-connection registration to eliminate
the unused duplicate API endpoint and reduce surface area.


// Resource and configuration endpoints
deploymentsRoute.GET("/hardware-types", controller.GetHardwareTypes)
deploymentsRoute.GET("/locations", controller.GetLocations)
deploymentsRoute.GET("/available-replicas", controller.GetAvailableReplicas)
deploymentsRoute.POST("/price-estimation", controller.GetPriceEstimation)
deploymentsRoute.GET("/check-name", controller.CheckClusterNameAvailability)

// Create new deployment
deploymentsRoute.POST("/", controller.CreateDeployment)

// Individual deployment operations
deploymentsRoute.GET("/:id", controller.GetDeployment)
deploymentsRoute.GET("/:id/logs", controller.GetDeploymentLogs)
deploymentsRoute.GET("/:id/containers", controller.ListDeploymentContainers)
Expand All @@ -295,14 +289,6 @@ func SetApiRouter(router *gin.Engine) {
deploymentsRoute.PUT("/:id/name", controller.UpdateDeploymentName)
deploymentsRoute.POST("/:id/extend", controller.ExtendDeployment)
deploymentsRoute.DELETE("/:id", controller.DeleteDeployment)

// Future batch operations:
// deploymentsRoute.POST("/:id/start", controller.StartDeployment)
// deploymentsRoute.POST("/:id/stop", controller.StopDeployment)
// deploymentsRoute.POST("/:id/restart", controller.RestartDeployment)
// deploymentsRoute.POST("/batch_delete", controller.BatchDeleteDeployments)
// deploymentsRoute.POST("/batch_start", controller.BatchStartDeployments)
// deploymentsRoute.POST("/batch_stop", controller.BatchStopDeployments)
}
}
}
4 changes: 3 additions & 1 deletion web/i18next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ export default defineConfig({
"zh",
"en",
"fr",
"ru"
"ru",
"ja",
"vi"
],
extract: {
input: [
Expand Down
Loading