-
Notifications
You must be signed in to change notification settings - Fork 734
Expand file tree
/
Copy pathconnection.go
More file actions
152 lines (132 loc) · 5.11 KB
/
connection.go
File metadata and controls
152 lines (132 loc) · 5.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package api
import (
"net/http"
"github.com/apache/incubator-devlake/core/errors"
"github.com/apache/incubator-devlake/core/plugin"
"github.com/apache/incubator-devlake/helpers/pluginhelper/api"
"github.com/apache/incubator-devlake/plugins/q_dev/models"
)
// 连接项目的CRUD API
// PostConnections 创建新连接 (enhanced with Identity Store validation)
func PostConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
// 创建连接
connection := &models.QDevConnection{}
err := api.Decode(input.Body, connection, vld)
if err != nil {
return nil, err
}
// 验证连接参数 (enhanced validation)
if err := validateConnection(connection); err != nil {
return nil, errors.BadInput.Wrap(err, "connection validation failed")
}
// 保存到数据库
err = connectionHelper.Create(connection, input)
if err != nil {
return nil, err
}
return &plugin.ApiResourceOutput{Body: connection.Sanitize(), Status: http.StatusOK}, nil
}
// PatchConnection 更新现有连接 (enhanced with Identity Store validation)
func PatchConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
connection := &models.QDevConnection{}
if err := connectionHelper.First(&connection, input.Params); err != nil {
return nil, err
}
if err := (&models.QDevConnection{}).MergeFromRequest(connection, input.Body); err != nil {
return nil, errors.Convert(err)
}
// 验证更新后的连接参数 (enhanced validation)
if err := validateConnection(connection); err != nil {
return nil, errors.BadInput.Wrap(err, "connection validation failed")
}
if err := connectionHelper.SaveWithCreateOrUpdate(connection); err != nil {
return nil, err
}
return &plugin.ApiResourceOutput{Body: connection.Sanitize(), Status: http.StatusOK}, nil
}
// DeleteConnection 删除连接
func DeleteConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
conn := &models.QDevConnection{}
output, err := connectionHelper.Delete(conn, input)
if err != nil {
return output, err
}
output.Body = conn.Sanitize()
return output, nil
}
// ListConnections 列出所有连接
func ListConnections(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
var connections []models.QDevConnection
err := connectionHelper.List(&connections)
if err != nil {
return nil, err
}
// 敏感信息脱敏
for i := 0; i < len(connections); i++ {
connections[i] = connections[i].Sanitize()
}
return &plugin.ApiResourceOutput{Body: connections}, nil
}
// GetConnection 获取单个连接详情
func GetConnection(input *plugin.ApiResourceInput) (*plugin.ApiResourceOutput, errors.Error) {
connection := &models.QDevConnection{}
err := connectionHelper.First(connection, input.Params)
if err != nil {
return nil, err
}
return &plugin.ApiResourceOutput{Body: connection.Sanitize()}, err
}
// validateConnection validates connection parameters including Identity Store fields
func validateConnection(connection *models.QDevConnection) error {
// Default to access_key auth type if not specified
if connection.AuthType == "" {
connection.AuthType = "access_key"
}
if connection.AuthType != "access_key" && connection.AuthType != "iam_role" {
return errors.Default.New("AuthType must be 'access_key' or 'iam_role'")
}
// Validate AWS credentials only for access_key auth type
if !connection.IsIAMRoleAuth() {
if connection.AccessKeyId == "" {
return errors.Default.New("AccessKeyId is required")
}
if connection.SecretAccessKey == "" {
return errors.Default.New("SecretAccessKey is required")
}
}
if connection.Region == "" {
return errors.Default.New("Region is required")
}
if connection.Bucket == "" {
return errors.Default.New("Bucket is required")
}
// Identity Store fields are optional, but must be provided together if used
if connection.IdentityStoreId == "" && connection.IdentityStoreRegion != "" {
return errors.Default.New("IdentityStoreRegion provided but IdentityStoreId is empty")
}
if connection.IdentityStoreId != "" && connection.IdentityStoreRegion == "" {
return errors.Default.New("IdentityStoreId provided but IdentityStoreRegion is empty")
}
// Validate rate limit
if connection.RateLimitPerHour < 0 {
return errors.Default.New("RateLimitPerHour must be positive")
}
if connection.RateLimitPerHour == 0 {
connection.RateLimitPerHour = 20000 // Set default value
}
return nil
}