Dragonfly2

Форк
0
273 строки · 8.4 Кб
1
/*
2
 *     Copyright 2020 The Dragonfly Authors
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *      http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16

17
package router
18

19
import (
20
	"net/http"
21
	"time"
22

23
	"github.com/casbin/casbin/v2"
24
	"github.com/gin-contrib/gzip"
25
	"github.com/gin-contrib/static"
26
	ginzap "github.com/gin-contrib/zap"
27
	"github.com/gin-gonic/gin"
28
	ginprometheus "github.com/mcuadros/go-gin-prometheus"
29
	swaggerFiles "github.com/swaggo/files"
30
	ginSwagger "github.com/swaggo/gin-swagger"
31
	"go.opentelemetry.io/contrib/instrumentation/github.com/gin-gonic/gin/otelgin"
32

33
	logger "d7y.io/dragonfly/v2/internal/dflog"
34
	"d7y.io/dragonfly/v2/manager/config"
35
	"d7y.io/dragonfly/v2/manager/database"
36
	"d7y.io/dragonfly/v2/manager/handlers"
37
	"d7y.io/dragonfly/v2/manager/middlewares"
38
	"d7y.io/dragonfly/v2/manager/service"
39
)
40

41
const (
42
	PrometheusSubsystemName = "dragonfly_manager"
43
	OtelServiceName         = "dragonfly-manager"
44
)
45

46
func Init(cfg *config.Config, logDir string, service service.Service, database *database.Database, enforcer *casbin.Enforcer, assets static.ServeFileSystem) (*gin.Engine, error) {
47
	// Set mode.
48
	if !cfg.Verbose {
49
		gin.SetMode(gin.ReleaseMode)
50
	}
51

52
	r := gin.New()
53
	h := handlers.New(service)
54

55
	// Prometheus metrics.
56
	p := ginprometheus.NewPrometheus(PrometheusSubsystemName)
57
	// URL removes query string.
58
	// Prometheus metrics need to reduce label,
59
	// refer to https://prometheus.io/docs/practices/instrumentation/#do-not-overuse-labels.
60
	p.ReqCntURLLabelMappingFn = func(c *gin.Context) string {
61
		return c.Request.URL.Path
62
	}
63
	p.Use(r)
64

65
	// Opentelemetry.
66
	if cfg.Options.Telemetry.Jaeger != "" {
67
		r.Use(otelgin.Middleware(OtelServiceName))
68
	}
69

70
	// Gin middleware.
71
	r.Use(gin.Recovery())
72
	r.Use(ginzap.Ginzap(logger.GinLogger.Desugar(), time.RFC3339, true))
73
	r.Use(ginzap.RecoveryWithZap(logger.GinLogger.Desugar(), true))
74

75
	// Error middleware.
76
	r.Use(middlewares.Error())
77

78
	// CORS middleware.
79
	r.Use(middlewares.CORS())
80

81
	// gzip middleware.
82
	r.Use(gzip.Gzip(gzip.DefaultCompression, gzip.WithExcludedExtensions([]string{".js", ".css"})))
83

84
	// RBAC middleware.
85
	rbac := middlewares.RBAC(enforcer)
86
	jwt, err := middlewares.Jwt(cfg.Auth.JWT, service)
87
	if err != nil {
88
		return nil, err
89
	}
90

91
	// Personal access token middleware.
92
	personalAccessToken := middlewares.PersonalAccessToken(database.DB)
93

94
	// Manager view.
95
	r.Use(static.Serve("/", assets))
96

97
	// API router.
98
	apiv1 := r.Group("/api/v1")
99

100
	// User.
101
	u := apiv1.Group("/users")
102
	u.PATCH(":id", jwt.MiddlewareFunc(), rbac, h.UpdateUser)
103
	u.GET(":id", jwt.MiddlewareFunc(), rbac, h.GetUser)
104
	u.GET("", jwt.MiddlewareFunc(), rbac, h.GetUsers)
105
	u.POST("signin", jwt.LoginHandler)
106
	u.POST("signout", jwt.LogoutHandler)
107
	u.POST("signup", h.SignUp)
108
	u.GET("signin/:name", h.OauthSignin)
109
	u.GET("signin/:name/callback", h.OauthSigninCallback(jwt))
110
	u.POST("refresh_token", jwt.RefreshHandler)
111
	u.POST(":id/reset_password", h.ResetPassword)
112
	u.GET(":id/roles", jwt.MiddlewareFunc(), rbac, h.GetRolesForUser)
113
	u.PUT(":id/roles/:role", jwt.MiddlewareFunc(), rbac, h.AddRoleToUser)
114
	u.DELETE(":id/roles/:role", jwt.MiddlewareFunc(), rbac, h.DeleteRoleForUser)
115

116
	// Role.
117
	re := apiv1.Group("/roles", jwt.MiddlewareFunc(), rbac)
118
	re.POST("", h.CreateRole)
119
	re.DELETE(":role", h.DestroyRole)
120
	re.GET(":role", h.GetRole)
121
	re.GET("", h.GetRoles)
122
	re.POST(":role/permissions", h.AddPermissionForRole)
123
	re.DELETE(":role/permissions", h.DeletePermissionForRole)
124

125
	// Permission.
126
	pm := apiv1.Group("/permissions", jwt.MiddlewareFunc(), rbac)
127
	pm.GET("", h.GetPermissions(r))
128

129
	// Oauth.
130
	oa := apiv1.Group("/oauth")
131
	oa.POST("", jwt.MiddlewareFunc(), rbac, h.CreateOauth)
132
	oa.DELETE(":id", jwt.MiddlewareFunc(), rbac, h.DestroyOauth)
133
	oa.PATCH(":id", jwt.MiddlewareFunc(), rbac, h.UpdateOauth)
134
	oa.GET(":id", h.GetOauth)
135
	oa.GET("", h.GetOauths)
136

137
	// Cluster.
138
	c := apiv1.Group("/clusters", jwt.MiddlewareFunc(), rbac)
139
	c.POST("", h.CreateCluster)
140
	c.DELETE(":id", h.DestroyCluster)
141
	c.PATCH(":id", h.UpdateCluster)
142
	c.GET(":id", h.GetCluster)
143
	c.GET("", h.GetClusters)
144

145
	// Scheduler Cluster.
146
	sc := apiv1.Group("/scheduler-clusters", jwt.MiddlewareFunc(), rbac)
147
	sc.POST("", h.CreateSchedulerCluster)
148
	sc.DELETE(":id", h.DestroySchedulerCluster)
149
	sc.PATCH(":id", h.UpdateSchedulerCluster)
150
	sc.GET(":id", h.GetSchedulerCluster)
151
	sc.GET("", h.GetSchedulerClusters)
152
	sc.PUT(":id/schedulers/:scheduler_id", h.AddSchedulerToSchedulerCluster)
153

154
	// Scheduler.
155
	s := apiv1.Group("/schedulers", jwt.MiddlewareFunc(), rbac)
156
	s.POST("", h.CreateScheduler)
157
	s.DELETE(":id", h.DestroyScheduler)
158
	s.PATCH(":id", h.UpdateScheduler)
159
	s.GET(":id", h.GetScheduler)
160
	s.GET("", h.GetSchedulers)
161

162
	// Seed Peer Cluster.
163
	spc := apiv1.Group("/seed-peer-clusters", jwt.MiddlewareFunc(), rbac)
164
	spc.POST("", h.CreateSeedPeerCluster)
165
	spc.DELETE(":id", h.DestroySeedPeerCluster)
166
	spc.PATCH(":id", h.UpdateSeedPeerCluster)
167
	spc.GET(":id", h.GetSeedPeerCluster)
168
	spc.GET("", h.GetSeedPeerClusters)
169
	spc.PUT(":id/seed-peers/:seed_peer_id", h.AddSeedPeerToSeedPeerCluster)
170
	spc.PUT(":id/scheduler-clusters/:scheduler_cluster_id", h.AddSchedulerClusterToSeedPeerCluster)
171

172
	// Seed Peer.
173
	sp := apiv1.Group("/seed-peers", jwt.MiddlewareFunc(), rbac)
174
	sp.POST("", h.CreateSeedPeer)
175
	sp.DELETE(":id", h.DestroySeedPeer)
176
	sp.PATCH(":id", h.UpdateSeedPeer)
177
	sp.GET(":id", h.GetSeedPeer)
178
	sp.GET("", h.GetSeedPeers)
179

180
	// Peer.
181
	peer := apiv1.Group("/peers", jwt.MiddlewareFunc(), rbac)
182
	peer.POST("", h.CreatePeer)
183
	peer.DELETE(":id", h.DestroyPeer)
184
	peer.GET(":id", h.GetPeer)
185
	peer.GET("", h.GetPeers)
186

187
	// Bucket.
188
	bucket := apiv1.Group("/buckets", jwt.MiddlewareFunc(), rbac)
189
	bucket.POST("", h.CreateBucket)
190
	bucket.DELETE(":id", h.DestroyBucket)
191
	bucket.GET(":id", h.GetBucket)
192
	bucket.GET("", h.GetBuckets)
193

194
	// Config.
195
	config := apiv1.Group("/configs")
196
	config.POST("", jwt.MiddlewareFunc(), rbac, h.CreateConfig)
197
	config.DELETE(":id", jwt.MiddlewareFunc(), rbac, h.DestroyConfig)
198
	config.PATCH(":id", jwt.MiddlewareFunc(), rbac, h.UpdateConfig)
199
	config.GET(":id", jwt.MiddlewareFunc(), rbac, h.GetConfig)
200
	config.GET("", h.GetConfigs)
201

202
	// TODO Add auth to the following routes and fix the tests.
203
	// Job.
204
	job := apiv1.Group("/jobs")
205
	job.POST("", h.CreateJob)
206
	job.DELETE(":id", h.DestroyJob)
207
	job.PATCH(":id", h.UpdateJob)
208
	job.GET(":id", h.GetJob)
209
	job.GET("", h.GetJobs)
210

211
	// Application.
212
	cs := apiv1.Group("/applications", jwt.MiddlewareFunc(), rbac)
213
	cs.POST("", h.CreateApplication)
214
	cs.DELETE(":id", h.DestroyApplication)
215
	cs.PATCH(":id", h.UpdateApplication)
216
	cs.GET(":id", h.GetApplication)
217
	cs.GET("", h.GetApplications)
218

219
	// Model.
220
	model := apiv1.Group("/models", jwt.MiddlewareFunc(), rbac)
221
	model.DELETE(":id", h.DestroyModel)
222
	model.PATCH(":id", h.UpdateModel)
223
	model.GET(":id", h.GetModel)
224
	model.GET("", h.GetModels)
225

226
	// Personal Access Token.
227
	pat := apiv1.Group("/personal-access-tokens", jwt.MiddlewareFunc(), rbac)
228
	pat.POST("", h.CreatePersonalAccessToken)
229
	pat.DELETE(":id", h.DestroyPersonalAccessToken)
230
	pat.PATCH(":id", h.UpdatePersonalAccessToken)
231
	pat.GET(":id", h.GetPersonalAccessToken)
232
	pat.GET("", h.GetPersonalAccessTokens)
233

234
	// Open API router.
235
	oapiv1 := r.Group("/oapi/v1")
236

237
	// Job.
238
	ojob := oapiv1.Group("/jobs", personalAccessToken)
239
	ojob.POST("", h.CreateJob)
240
	ojob.DELETE(":id", h.DestroyJob)
241
	ojob.PATCH(":id", h.UpdateJob)
242
	ojob.GET(":id", h.GetJob)
243
	ojob.GET("", h.GetJobs)
244

245
	// Cluster.
246
	oc := oapiv1.Group("/clusters", personalAccessToken)
247
	oc.POST("", h.CreateCluster)
248
	oc.DELETE(":id", h.DestroyCluster)
249
	oc.PATCH(":id", h.UpdateCluster)
250
	oc.GET(":id", h.GetCluster)
251
	oc.GET("", h.GetClusters)
252

253
	// TODO Remove this api.
254
	// Compatible with the V1 preheat.
255
	pv1 := r.Group("/preheats")
256
	r.GET("_ping", h.GetHealth)
257
	pv1.POST("", h.CreateV1Preheat)
258
	pv1.GET(":id", h.GetV1Preheat)
259

260
	// Health Check.
261
	r.GET("/healthy", h.GetHealth)
262

263
	// Swagger.
264
	apiSeagger := ginSwagger.URL("/swagger/doc.json")
265
	r.GET("/swagger/*any", ginSwagger.WrapHandler(swaggerFiles.Handler, apiSeagger))
266

267
	// Fallback to manager view.
268
	r.NoRoute(func(c *gin.Context) {
269
		c.Redirect(http.StatusMovedPermanently, "/")
270
	})
271

272
	return r, nil
273
}
274

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.