deployment_target.go 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. package router
  2. import (
  3. "fmt"
  4. "github.com/go-chi/chi/v5"
  5. "github.com/porter-dev/porter/api/server/handlers/addons"
  6. "github.com/porter-dev/porter/api/server/handlers/deployment_target"
  7. "github.com/porter-dev/porter/api/server/handlers/porter_app"
  8. "github.com/porter-dev/porter/api/server/shared"
  9. "github.com/porter-dev/porter/api/server/shared/config"
  10. "github.com/porter-dev/porter/api/server/shared/router"
  11. "github.com/porter-dev/porter/api/types"
  12. )
  13. // NewDeploymentTargetScopedRegisterer applies /api/projects/{project_id}/targets routes to the gin Router
  14. func NewDeploymentTargetScopedRegisterer(children ...*router.Registerer) *router.Registerer {
  15. return &router.Registerer{
  16. GetRoutes: GetDeploymentTargetScopedRoutes,
  17. Children: children,
  18. }
  19. }
  20. // GetDeploymentTargetScopedRoutes returns the router handlers specific to deployment targets
  21. func GetDeploymentTargetScopedRoutes(
  22. r chi.Router,
  23. config *config.Config,
  24. basePath *types.Path,
  25. factory shared.APIEndpointFactory,
  26. children ...*router.Registerer,
  27. ) []*router.Route {
  28. routes, projPath := getDeploymentTargetRoutes(r, config, basePath, factory)
  29. if len(children) > 0 {
  30. r.Route(projPath.RelativePath, func(r chi.Router) {
  31. for _, child := range children {
  32. childRoutes := child.GetRoutes(r, config, basePath, factory, child.Children...)
  33. routes = append(routes, childRoutes...)
  34. }
  35. })
  36. }
  37. return routes
  38. }
  39. // getDeploymentTargetRoutes gets the routes that use deployment targets as a first class object instead of scoped to clusters
  40. func getDeploymentTargetRoutes(
  41. r chi.Router,
  42. config *config.Config,
  43. basePath *types.Path,
  44. factory shared.APIEndpointFactory,
  45. ) ([]*router.Route, *types.Path) {
  46. relPath := "/targets/{deployment_target_identifier}"
  47. newPath := &types.Path{
  48. Parent: basePath,
  49. RelativePath: relPath,
  50. }
  51. var routes []*router.Route
  52. // GET /api/projects/{project_id}/targets/{deployment_target_identifier} -> deployment_target.GetDeploymentTargetHandler
  53. getDeploymentTargetEndpoint := factory.NewAPIEndpoint(
  54. &types.APIRequestMetadata{
  55. Verb: types.APIVerbGet,
  56. Method: types.HTTPVerbGet,
  57. Path: &types.Path{
  58. Parent: basePath,
  59. RelativePath: relPath,
  60. },
  61. Scopes: []types.PermissionScope{
  62. types.UserScope,
  63. types.ProjectScope,
  64. types.DeploymentTargetScope,
  65. },
  66. },
  67. )
  68. getDeploymentTargetHandler := deployment_target.NewGetDeploymentTargetHandler(
  69. config,
  70. factory.GetDecoderValidator(),
  71. factory.GetResultWriter(),
  72. )
  73. routes = append(routes, &router.Route{
  74. Endpoint: getDeploymentTargetEndpoint,
  75. Handler: getDeploymentTargetHandler,
  76. Router: r,
  77. })
  78. // GET /api/projects/{project_id}/targets/{deployment_target_identifier}/apps/{porter_app_name}/cloudsql -> porter_app.GetCloudSqlSecretHandler
  79. getCloudSqlSecretEndpoint := factory.NewAPIEndpoint(
  80. &types.APIRequestMetadata{
  81. Verb: types.APIVerbGet,
  82. Method: types.HTTPVerbGet,
  83. Path: &types.Path{
  84. Parent: basePath,
  85. RelativePath: fmt.Sprintf("%s/apps/{porter_app_name}/cloudsql", relPath),
  86. },
  87. Scopes: []types.PermissionScope{
  88. types.UserScope,
  89. types.ProjectScope,
  90. types.DeploymentTargetScope,
  91. },
  92. },
  93. )
  94. getCloudSqlSecretHandler := porter_app.NewGetCloudSqlSecretHandler(
  95. config,
  96. factory.GetResultWriter(),
  97. )
  98. routes = append(routes, &router.Route{
  99. Endpoint: getCloudSqlSecretEndpoint,
  100. Handler: getCloudSqlSecretHandler,
  101. Router: r,
  102. })
  103. // POST /api/projects/{project_id}/targets/{deployment_target_identifier}/apps/{porter_app_name}/cloudsql -> porter_app.CreateCloudSqlSecretHandler
  104. createCloudSqlSecretEndpoint := factory.NewAPIEndpoint(
  105. &types.APIRequestMetadata{
  106. Verb: types.APIVerbCreate,
  107. Method: types.HTTPVerbPost,
  108. Path: &types.Path{
  109. Parent: basePath,
  110. RelativePath: fmt.Sprintf("%s/apps/{porter_app_name}/cloudsql", relPath),
  111. },
  112. Scopes: []types.PermissionScope{
  113. types.UserScope,
  114. types.ProjectScope,
  115. types.DeploymentTargetScope,
  116. },
  117. },
  118. )
  119. createCloudSqlSecretHandler := porter_app.NewCreateCloudSqlSecretHandler(
  120. config,
  121. factory.GetDecoderValidator(),
  122. factory.GetResultWriter(),
  123. )
  124. routes = append(routes, &router.Route{
  125. Endpoint: createCloudSqlSecretEndpoint,
  126. Handler: createCloudSqlSecretHandler,
  127. Router: r,
  128. })
  129. // GET /api/projects/{project_id}/targets/{deployment_target_identifier}/addons -> addons.LatestAddonsHandler
  130. listAddonsEndpoint := factory.NewAPIEndpoint(
  131. &types.APIRequestMetadata{
  132. Verb: types.APIVerbGet,
  133. Method: types.HTTPVerbGet,
  134. Path: &types.Path{
  135. Parent: basePath,
  136. RelativePath: fmt.Sprintf("%s/addons", relPath),
  137. },
  138. Scopes: []types.PermissionScope{
  139. types.UserScope,
  140. types.ProjectScope,
  141. types.DeploymentTargetScope,
  142. },
  143. },
  144. )
  145. listAddonsHandler := addons.NewLatestAddonsHandler(
  146. config,
  147. factory.GetDecoderValidator(),
  148. factory.GetResultWriter(),
  149. )
  150. routes = append(routes, &router.Route{
  151. Endpoint: listAddonsEndpoint,
  152. Handler: listAddonsHandler,
  153. Router: r,
  154. })
  155. // GET /api/projects/{project_id}/targets/{deployment_target_identifier}/addons/{addon_name} -> addons.AddonHandler
  156. addonEndpoint := factory.NewAPIEndpoint(
  157. &types.APIRequestMetadata{
  158. Verb: types.APIVerbGet,
  159. Method: types.HTTPVerbGet,
  160. Path: &types.Path{
  161. Parent: basePath,
  162. RelativePath: fmt.Sprintf("%s/addons/{%s}", relPath, types.URLParamAddonName),
  163. },
  164. Scopes: []types.PermissionScope{
  165. types.UserScope,
  166. types.ProjectScope,
  167. types.DeploymentTargetScope,
  168. },
  169. },
  170. )
  171. addonHandler := addons.NewAddonHandler(
  172. config,
  173. factory.GetDecoderValidator(),
  174. factory.GetResultWriter(),
  175. )
  176. routes = append(routes, &router.Route{
  177. Endpoint: addonEndpoint,
  178. Handler: addonHandler,
  179. Router: r,
  180. })
  181. // GET /api/projects/{project_id}/targets/{deployment_target_identifier}/addons/tailscale-services -> addons.TailscaleServicesHandler
  182. tailscaleServicesEndpoint := factory.NewAPIEndpoint(
  183. &types.APIRequestMetadata{
  184. Verb: types.APIVerbGet,
  185. Method: types.HTTPVerbGet,
  186. Path: &types.Path{
  187. Parent: basePath,
  188. RelativePath: fmt.Sprintf("%s/addons/tailscale-services", relPath),
  189. },
  190. Scopes: []types.PermissionScope{
  191. types.UserScope,
  192. types.ProjectScope,
  193. types.DeploymentTargetScope,
  194. },
  195. },
  196. )
  197. tailscaleServicesHandler := addons.NewTailscaleServicesHandler(
  198. config,
  199. factory.GetDecoderValidator(),
  200. factory.GetResultWriter(),
  201. )
  202. routes = append(routes, &router.Route{
  203. Endpoint: tailscaleServicesEndpoint,
  204. Handler: tailscaleServicesHandler,
  205. Router: r,
  206. })
  207. // POST /api/projects/{project_id}/targets/{deployment_target_identifier}/addons/update -> addons.UpdateAddonHandler
  208. updateAddonEndpoint := factory.NewAPIEndpoint(
  209. &types.APIRequestMetadata{
  210. Verb: types.APIVerbUpdate,
  211. Method: types.HTTPVerbPost,
  212. Path: &types.Path{
  213. Parent: basePath,
  214. RelativePath: fmt.Sprintf("%s/addons/update", relPath),
  215. },
  216. Scopes: []types.PermissionScope{
  217. types.UserScope,
  218. types.ProjectScope,
  219. types.DeploymentTargetScope,
  220. },
  221. },
  222. )
  223. updateAddonHandler := addons.NewUpdateAddonHandler(
  224. config,
  225. factory.GetDecoderValidator(),
  226. factory.GetResultWriter(),
  227. )
  228. routes = append(routes, &router.Route{
  229. Endpoint: updateAddonEndpoint,
  230. Handler: updateAddonHandler,
  231. Router: r,
  232. })
  233. // DELETE /api/projects/{project_id}/targets/{deployment_target_identifier}/addons/{addon_name} -> addons.DeleteAddonHandler
  234. deleteAddonEndpoint := factory.NewAPIEndpoint(
  235. &types.APIRequestMetadata{
  236. Verb: types.APIVerbDelete,
  237. Method: types.HTTPVerbDelete,
  238. Path: &types.Path{
  239. Parent: basePath,
  240. RelativePath: fmt.Sprintf("%s/addons/{%s}", relPath, types.URLParamAddonName),
  241. },
  242. Scopes: []types.PermissionScope{
  243. types.UserScope,
  244. types.ProjectScope,
  245. types.DeploymentTargetScope,
  246. },
  247. },
  248. )
  249. deleteAddonHandler := addons.NewDeleteAddonHandler(
  250. config,
  251. factory.GetDecoderValidator(),
  252. factory.GetResultWriter(),
  253. )
  254. routes = append(routes, &router.Route{
  255. Endpoint: deleteAddonEndpoint,
  256. Handler: deleteAddonHandler,
  257. Router: r,
  258. })
  259. // POST /api/projects/{project_id}/targets/{deployment_target_identifier}/apps/{porter_app_name}/app-event-webhooks -> porter_app.NewAppEventWebhooksHandler
  260. appEventWebhooks := factory.NewAPIEndpoint(
  261. &types.APIRequestMetadata{
  262. Verb: types.APIVerbGet,
  263. Method: types.HTTPVerbGet,
  264. Path: &types.Path{
  265. Parent: basePath,
  266. RelativePath: fmt.Sprintf("%s/apps/{%s}/app-event-webhooks", relPath, types.URLParamPorterAppName),
  267. },
  268. Scopes: []types.PermissionScope{
  269. types.UserScope,
  270. types.ProjectScope,
  271. types.DeploymentTargetScope,
  272. },
  273. },
  274. )
  275. appEventWebhooksHandler := porter_app.NewAppEventWebhooksHandler(
  276. config,
  277. factory.GetDecoderValidator(),
  278. factory.GetResultWriter(),
  279. )
  280. routes = append(routes, &router.Route{
  281. Endpoint: appEventWebhooks,
  282. Handler: appEventWebhooksHandler,
  283. Router: r,
  284. })
  285. // POST /api/projects/{project_id}/targets/{deployment_target_identifier}/apps/{porter_app_name}/update-app-event-webhooks-> porter_app.NewUpdateAppEventWebhookHandler
  286. updateAppEventWebhooks := factory.NewAPIEndpoint(
  287. &types.APIRequestMetadata{
  288. Verb: types.APIVerbCreate,
  289. Method: types.HTTPVerbPost,
  290. Path: &types.Path{
  291. Parent: basePath,
  292. RelativePath: fmt.Sprintf("%s/apps/{%s}/update-app-event-webhooks", relPath, types.URLParamPorterAppName),
  293. },
  294. Scopes: []types.PermissionScope{
  295. types.UserScope,
  296. types.ProjectScope,
  297. types.DeploymentTargetScope,
  298. },
  299. },
  300. )
  301. updateAppEventWebhooksHandler := porter_app.NewUpdateAppEventWebhookHandler(
  302. config,
  303. factory.GetDecoderValidator(),
  304. factory.GetResultWriter(),
  305. )
  306. routes = append(routes, &router.Route{
  307. Endpoint: updateAppEventWebhooks,
  308. Handler: updateAppEventWebhooksHandler,
  309. Router: r,
  310. })
  311. return routes, newPath
  312. }