porter_app.go 29 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069
  1. package router
  2. import (
  3. "fmt"
  4. "github.com/go-chi/chi/v5"
  5. "github.com/porter-dev/porter/api/server/handlers/porter_app"
  6. "github.com/porter-dev/porter/api/server/shared"
  7. "github.com/porter-dev/porter/api/server/shared/config"
  8. "github.com/porter-dev/porter/api/server/shared/router"
  9. "github.com/porter-dev/porter/api/types"
  10. )
  11. func NewPorterAppScopedRegisterer(children ...*router.Registerer) *router.Registerer {
  12. return &router.Registerer{
  13. GetRoutes: GetPorterAppScopedRoutes,
  14. Children: children,
  15. }
  16. }
  17. func GetPorterAppScopedRoutes(
  18. r chi.Router,
  19. config *config.Config,
  20. basePath *types.Path,
  21. factory shared.APIEndpointFactory,
  22. children ...*router.Registerer,
  23. ) []*router.Route {
  24. routes, projPath := getPorterAppRoutes(r, config, basePath, factory)
  25. if len(children) > 0 {
  26. r.Route(projPath.RelativePath, func(r chi.Router) {
  27. for _, child := range children {
  28. childRoutes := child.GetRoutes(r, config, basePath, factory, child.Children...)
  29. routes = append(routes, childRoutes...)
  30. }
  31. })
  32. }
  33. return routes
  34. }
  35. func getPorterAppRoutes(
  36. r chi.Router,
  37. config *config.Config,
  38. basePath *types.Path,
  39. factory shared.APIEndpointFactory,
  40. ) ([]*router.Route, *types.Path) {
  41. relPath := "/applications"
  42. newPath := &types.Path{
  43. Parent: basePath,
  44. RelativePath: relPath,
  45. }
  46. var routes []*router.Route
  47. // GET /api/projects/{project_id}/clusters/{cluster_id}/applications/{name} -> porter_app.NewPorterAppGetHandler
  48. getPorterAppEndpoint := factory.NewAPIEndpoint(
  49. &types.APIRequestMetadata{
  50. Verb: types.APIVerbGet,
  51. Method: types.HTTPVerbGet,
  52. Path: &types.Path{
  53. Parent: basePath,
  54. RelativePath: fmt.Sprintf("%s/{%s}", relPath, types.URLParamPorterAppName),
  55. },
  56. Scopes: []types.PermissionScope{
  57. types.UserScope,
  58. types.ProjectScope,
  59. types.ClusterScope,
  60. },
  61. },
  62. )
  63. getPorterAppHandler := porter_app.NewGetPorterAppHandler(
  64. config,
  65. factory.GetResultWriter(),
  66. )
  67. routes = append(routes, &router.Route{
  68. Endpoint: getPorterAppEndpoint,
  69. Handler: getPorterAppHandler,
  70. Router: r,
  71. })
  72. // GET /api/projects/{project_id}/clusters/{cluster_id}/applications/{name}/releases/{version} -> porter_app.NewPorterAppReleaseGetHandler
  73. getPorterAppHelmReleaseEndpoint := factory.NewAPIEndpoint(
  74. &types.APIRequestMetadata{
  75. Verb: types.APIVerbList,
  76. Method: types.HTTPVerbGet,
  77. Path: &types.Path{
  78. Parent: basePath,
  79. RelativePath: fmt.Sprintf("%s/{%s}/releases/{%s}", relPath, types.URLParamPorterAppName, types.URLParamReleaseVersion),
  80. },
  81. Scopes: []types.PermissionScope{
  82. types.UserScope,
  83. types.ProjectScope,
  84. types.ClusterScope,
  85. },
  86. },
  87. )
  88. getPorterAppHelmReleaseHandler := porter_app.NewPorterAppHelmReleaseGetHandler(
  89. config,
  90. factory.GetResultWriter(),
  91. )
  92. routes = append(routes, &router.Route{
  93. Endpoint: getPorterAppHelmReleaseEndpoint,
  94. Handler: getPorterAppHelmReleaseHandler,
  95. Router: r,
  96. })
  97. // GET /api/projects/{project_id}/clusters/{cluster_id}/applications/{name}/release-history -> porter_app.NewPorterAppHelmReleaseHistoryGetHandler
  98. getPorterAppHelmReleaseHistoryGetEndpoint := factory.NewAPIEndpoint(
  99. &types.APIRequestMetadata{
  100. Verb: types.APIVerbList,
  101. Method: types.HTTPVerbGet,
  102. Path: &types.Path{
  103. Parent: basePath,
  104. RelativePath: fmt.Sprintf("%s/{%s}/release-history", relPath, types.URLParamPorterAppName),
  105. },
  106. Scopes: []types.PermissionScope{
  107. types.UserScope,
  108. types.ProjectScope,
  109. types.ClusterScope,
  110. },
  111. },
  112. )
  113. getPorterAppHelmReleaseHistoryGetHandler := porter_app.NewPorterAppHelmReleaseHistoryGetHandler(
  114. config,
  115. factory.GetResultWriter(),
  116. )
  117. routes = append(routes, &router.Route{
  118. Endpoint: getPorterAppHelmReleaseHistoryGetEndpoint,
  119. Handler: getPorterAppHelmReleaseHistoryGetHandler,
  120. Router: r,
  121. })
  122. // GET /api/projects/{project_id}/clusters/{cluster_id}/applications/{name}/releases/{version}/pods/all -> porter_app.NewPorterAppPodsGetHandler
  123. getPorterAppPodsEndpoint := factory.NewAPIEndpoint(
  124. &types.APIRequestMetadata{
  125. Verb: types.APIVerbList,
  126. Method: types.HTTPVerbGet,
  127. Path: &types.Path{
  128. Parent: basePath,
  129. RelativePath: fmt.Sprintf("%s/{%s}/releases/{%s}/pods/all", relPath, types.URLParamPorterAppName, types.URLParamReleaseVersion),
  130. },
  131. Scopes: []types.PermissionScope{
  132. types.UserScope,
  133. types.ProjectScope,
  134. types.ClusterScope,
  135. },
  136. },
  137. )
  138. getPorterAppPodsHandler := porter_app.NewPorterAppPodsGetHandler(
  139. config,
  140. factory.GetResultWriter(),
  141. )
  142. routes = append(routes, &router.Route{
  143. Endpoint: getPorterAppPodsEndpoint,
  144. Handler: getPorterAppPodsHandler,
  145. Router: r,
  146. })
  147. // GET /api/projects/{project_id}/clusters/{cluster_id}/applications -> porter_app.NewPorterAppListHandler
  148. listPorterAppEndpoint := factory.NewAPIEndpoint(
  149. &types.APIRequestMetadata{
  150. Verb: types.APIVerbList,
  151. Method: types.HTTPVerbGet,
  152. Path: &types.Path{
  153. Parent: basePath,
  154. RelativePath: relPath,
  155. },
  156. Scopes: []types.PermissionScope{
  157. types.UserScope,
  158. types.ProjectScope,
  159. types.ClusterScope,
  160. },
  161. },
  162. )
  163. listPorterAppHandler := porter_app.NewPorterAppListHandler(
  164. config,
  165. factory.GetResultWriter(),
  166. )
  167. routes = append(routes, &router.Route{
  168. Endpoint: listPorterAppEndpoint,
  169. Handler: listPorterAppHandler,
  170. Router: r,
  171. })
  172. // DELETE /api/projects/{project_id}/clusters/{cluster_id}/applications/{porter_app_name} -> release.NewDeletePorterAppByNameHandler
  173. deletePorterAppByNameEndpoint := factory.NewAPIEndpoint(
  174. &types.APIRequestMetadata{
  175. Verb: types.APIVerbDelete,
  176. Method: types.HTTPVerbDelete,
  177. Path: &types.Path{
  178. Parent: basePath,
  179. RelativePath: fmt.Sprintf("%s/{%s}", relPath, types.URLParamPorterAppName),
  180. },
  181. Scopes: []types.PermissionScope{
  182. types.UserScope,
  183. types.ProjectScope,
  184. types.ClusterScope,
  185. },
  186. },
  187. )
  188. deletePorterAppByNameHandler := porter_app.NewDeletePorterAppByNameHandler(
  189. config,
  190. factory.GetDecoderValidator(),
  191. factory.GetResultWriter(),
  192. )
  193. routes = append(routes, &router.Route{
  194. Endpoint: deletePorterAppByNameEndpoint,
  195. Handler: deletePorterAppByNameHandler,
  196. Router: r,
  197. })
  198. // POST /api/projects/{project_id}/clusters/{cluster_id}/applications/{porter_app_name} -> porter_app.NewCreatePorterAppHandler
  199. createPorterAppEndpoint := factory.NewAPIEndpoint(
  200. &types.APIRequestMetadata{
  201. Verb: types.APIVerbCreate,
  202. Method: types.HTTPVerbPost,
  203. Path: &types.Path{
  204. Parent: basePath,
  205. RelativePath: fmt.Sprintf("%s/{%s}", relPath, types.URLParamPorterAppName),
  206. },
  207. Scopes: []types.PermissionScope{
  208. types.UserScope,
  209. types.ProjectScope,
  210. types.ClusterScope,
  211. },
  212. },
  213. )
  214. createPorterAppHandler := porter_app.NewCreatePorterAppHandler(
  215. config,
  216. factory.GetDecoderValidator(),
  217. factory.GetResultWriter(),
  218. )
  219. routes = append(routes, &router.Route{
  220. Endpoint: createPorterAppEndpoint,
  221. Handler: createPorterAppHandler,
  222. Router: r,
  223. })
  224. // POST /api/projects/{project_id}/clusters/{cluster_id}/applications/{porter_app_name}/rollback -> porter_app.NewRollbackPorterAppHandler
  225. rollbackPorterAppEndpoint := factory.NewAPIEndpoint(
  226. &types.APIRequestMetadata{
  227. Verb: types.APIVerbCreate,
  228. Method: types.HTTPVerbPost,
  229. Path: &types.Path{
  230. Parent: basePath,
  231. RelativePath: fmt.Sprintf("%s/{%s}/rollback", relPath, types.URLParamPorterAppName),
  232. },
  233. Scopes: []types.PermissionScope{
  234. types.UserScope,
  235. types.ProjectScope,
  236. types.ClusterScope,
  237. },
  238. },
  239. )
  240. rollbackPorterAppHandler := porter_app.NewRollbackPorterAppHandler(
  241. config,
  242. factory.GetDecoderValidator(),
  243. factory.GetResultWriter(),
  244. )
  245. routes = append(routes, &router.Route{
  246. Endpoint: rollbackPorterAppEndpoint,
  247. Handler: rollbackPorterAppHandler,
  248. Router: r,
  249. })
  250. // POST /api/projects/{project_id}/clusters/{cluster_id}/applications/{porter_app_name}/pr -> porter_app.NewOpenStackPRHandler
  251. createSecretAndOpenGitHubPullRequestEndpoint := factory.NewAPIEndpoint(
  252. &types.APIRequestMetadata{
  253. Verb: types.APIVerbCreate,
  254. Method: types.HTTPVerbPost,
  255. Path: &types.Path{
  256. Parent: basePath,
  257. RelativePath: fmt.Sprintf("%s/{%s}/pr", relPath, types.URLParamPorterAppName),
  258. },
  259. Scopes: []types.PermissionScope{
  260. types.UserScope,
  261. types.ProjectScope,
  262. types.ClusterScope,
  263. },
  264. },
  265. )
  266. createSecretAndOpenGitHubPullRequestHandler := porter_app.NewOpenStackPRHandler(
  267. config,
  268. factory.GetDecoderValidator(),
  269. factory.GetResultWriter(),
  270. )
  271. routes = append(routes, &router.Route{
  272. Endpoint: createSecretAndOpenGitHubPullRequestEndpoint,
  273. Handler: createSecretAndOpenGitHubPullRequestHandler,
  274. Router: r,
  275. })
  276. // GET /api/projects/{project_id}/clusters/{cluster_id}/applications/{porter_app_name}/events -> porter_app.NewPorterAppEventListHandler
  277. listPorterAppEventsEndpoint := factory.NewAPIEndpoint(
  278. &types.APIRequestMetadata{
  279. Verb: types.APIVerbList,
  280. Method: types.HTTPVerbGet,
  281. Path: &types.Path{
  282. Parent: basePath,
  283. RelativePath: fmt.Sprintf("%s/{%s}/events", relPath, types.URLParamPorterAppName),
  284. },
  285. Scopes: []types.PermissionScope{
  286. types.UserScope,
  287. types.ProjectScope,
  288. types.ClusterScope,
  289. },
  290. },
  291. )
  292. listPorterAppEventsHandler := porter_app.NewPorterAppEventListHandler(
  293. config,
  294. factory.GetResultWriter(),
  295. )
  296. routes = append(routes, &router.Route{
  297. Endpoint: listPorterAppEventsEndpoint,
  298. Handler: listPorterAppEventsHandler,
  299. Router: r,
  300. })
  301. // POST /api/projects/{project_id}/clusters/{cluster_id}/applications/{name}/events -> porter_app.NewCreatePorterAppEventHandler
  302. createPorterAppEventEndpoint := factory.NewAPIEndpoint(
  303. &types.APIRequestMetadata{
  304. Verb: types.APIVerbCreate,
  305. Method: types.HTTPVerbPost,
  306. Path: &types.Path{
  307. Parent: basePath,
  308. RelativePath: fmt.Sprintf("%s/{%s}/events", relPath, types.URLParamPorterAppName),
  309. },
  310. Scopes: []types.PermissionScope{
  311. types.UserScope,
  312. types.ProjectScope,
  313. types.ClusterScope,
  314. },
  315. },
  316. )
  317. createPorterAppEventHandler := porter_app.NewCreateUpdatePorterAppEventHandler(
  318. config,
  319. factory.GetDecoderValidator(),
  320. factory.GetResultWriter(),
  321. )
  322. routes = append(routes, &router.Route{
  323. Endpoint: createPorterAppEventEndpoint,
  324. Handler: createPorterAppEventHandler,
  325. Router: r,
  326. })
  327. // GET /api/projects/{project_id}/clusters/{cluster_id}/events/id -> porter_app.NewGetPorterAppEventHandler
  328. getPorterAppEventEndpoint := factory.NewAPIEndpoint(
  329. &types.APIRequestMetadata{
  330. Verb: types.APIVerbCreate,
  331. Method: types.HTTPVerbGet,
  332. Path: &types.Path{
  333. Parent: basePath,
  334. RelativePath: fmt.Sprintf("/events/{%s}", types.URLParamPorterAppEventID),
  335. },
  336. Scopes: []types.PermissionScope{
  337. types.UserScope,
  338. types.ProjectScope,
  339. types.ClusterScope,
  340. },
  341. },
  342. )
  343. getPorterAppEventHandler := porter_app.NewGetPorterAppEventHandler(
  344. config,
  345. factory.GetResultWriter(),
  346. )
  347. routes = append(routes, &router.Route{
  348. Endpoint: getPorterAppEventEndpoint,
  349. Handler: getPorterAppEventHandler,
  350. Router: r,
  351. })
  352. // POST /api/projects/{project_id}/clusters/{cluster_id}/applications/analytics -> porter_app.NewPorterAppAnalyticsHandler
  353. porterAppAnalyticsEndpoint := factory.NewAPIEndpoint(
  354. &types.APIRequestMetadata{
  355. Verb: types.APIVerbUpdate,
  356. Method: types.HTTPVerbPost,
  357. Path: &types.Path{
  358. Parent: basePath,
  359. RelativePath: fmt.Sprintf("%s/analytics", relPath),
  360. },
  361. Scopes: []types.PermissionScope{
  362. types.UserScope,
  363. types.ProjectScope,
  364. types.ClusterScope,
  365. },
  366. },
  367. )
  368. porterAppAnalyticsHandler := porter_app.NewPorterAppAnalyticsHandler(
  369. config,
  370. factory.GetDecoderValidator(),
  371. factory.GetResultWriter(),
  372. )
  373. routes = append(routes, &router.Route{
  374. Endpoint: porterAppAnalyticsEndpoint,
  375. Handler: porterAppAnalyticsHandler,
  376. Router: r,
  377. })
  378. // GET /api/projects/{project_id}/clusters/{cluster_id}/applications/logs -> cluster.NewGetChartLogsWithinTimeRangeHandler
  379. getChartLogsWithinTimeRangeEndpoint := factory.NewAPIEndpoint(
  380. &types.APIRequestMetadata{
  381. Verb: types.APIVerbGet,
  382. Method: types.HTTPVerbGet,
  383. Path: &types.Path{
  384. Parent: basePath,
  385. RelativePath: fmt.Sprintf("%s/logs", relPath),
  386. },
  387. Scopes: []types.PermissionScope{
  388. types.UserScope,
  389. types.ProjectScope,
  390. types.ClusterScope,
  391. },
  392. },
  393. )
  394. getChartLogsWithinTimeRangeHandler := porter_app.NewGetLogsWithinTimeRangeHandler(
  395. config,
  396. factory.GetDecoderValidator(),
  397. factory.GetResultWriter(),
  398. )
  399. routes = append(routes, &router.Route{
  400. Endpoint: getChartLogsWithinTimeRangeEndpoint,
  401. Handler: getChartLogsWithinTimeRangeHandler,
  402. Router: r,
  403. })
  404. // POST /api/projects/{project_id}/clusters/{cluster_id}/applications/{porter_app_name}/run -> porter_app.NewRunPorterAppCommandHandler
  405. runPorterAppCommandEndpoint := factory.NewAPIEndpoint(
  406. &types.APIRequestMetadata{
  407. Verb: types.APIVerbCreate,
  408. Method: types.HTTPVerbPost,
  409. Path: &types.Path{
  410. Parent: basePath,
  411. RelativePath: fmt.Sprintf("%s/{%s}/run", relPath, types.URLParamPorterAppName),
  412. },
  413. Scopes: []types.PermissionScope{
  414. types.UserScope,
  415. types.ProjectScope,
  416. types.ClusterScope,
  417. },
  418. },
  419. )
  420. runPorterAppCommandHandler := porter_app.NewRunPorterAppCommandHandler(
  421. config,
  422. factory.GetDecoderValidator(),
  423. factory.GetResultWriter(),
  424. )
  425. routes = append(routes, &router.Route{
  426. Endpoint: runPorterAppCommandEndpoint,
  427. Handler: runPorterAppCommandHandler,
  428. Router: r,
  429. })
  430. // TODO: remove these three endpoints once these three 'stacks' routes are no longer used in telemetry
  431. // GET /api/projects/{project_id}/clusters/{cluster_id}/stacks/{name} -> porter_app.NewPorterAppGetHandler
  432. LEGACY_getPorterAppEndpoint := factory.NewAPIEndpoint(
  433. &types.APIRequestMetadata{
  434. Verb: types.APIVerbGet,
  435. Method: types.HTTPVerbGet,
  436. Path: &types.Path{
  437. Parent: basePath,
  438. RelativePath: fmt.Sprintf("/stacks/{%s}", types.URLParamPorterAppName),
  439. },
  440. Scopes: []types.PermissionScope{
  441. types.UserScope,
  442. types.ProjectScope,
  443. types.ClusterScope,
  444. },
  445. },
  446. )
  447. LEGACY_getPorterAppHandler := porter_app.NewGetPorterAppHandler(
  448. config,
  449. factory.GetResultWriter(),
  450. )
  451. routes = append(routes, &router.Route{
  452. Endpoint: LEGACY_getPorterAppEndpoint,
  453. Handler: LEGACY_getPorterAppHandler,
  454. Router: r,
  455. })
  456. // POST /api/projects/{project_id}/clusters/{cluster_id}/stacks/{porter_app_name} -> porter_app.NewCreatePorterAppHandler
  457. LEGACY_createPorterAppEndpoint := factory.NewAPIEndpoint(
  458. &types.APIRequestMetadata{
  459. Verb: types.APIVerbCreate,
  460. Method: types.HTTPVerbPost,
  461. Path: &types.Path{
  462. Parent: basePath,
  463. RelativePath: fmt.Sprintf("/stacks/{%s}", types.URLParamPorterAppName),
  464. },
  465. Scopes: []types.PermissionScope{
  466. types.UserScope,
  467. types.ProjectScope,
  468. types.ClusterScope,
  469. },
  470. },
  471. )
  472. LEGACY_createPorterAppHandler := porter_app.NewCreatePorterAppHandler(
  473. config,
  474. factory.GetDecoderValidator(),
  475. factory.GetResultWriter(),
  476. )
  477. routes = append(routes, &router.Route{
  478. Endpoint: LEGACY_createPorterAppEndpoint,
  479. Handler: LEGACY_createPorterAppHandler,
  480. Router: r,
  481. })
  482. // POST /api/projects/{project_id}/clusters/{cluster_id}/stacks/{name}/events -> porter_app.NewCreatePorterAppEventHandler
  483. LEGACY_createPorterAppEventEndpoint := factory.NewAPIEndpoint(
  484. &types.APIRequestMetadata{
  485. Verb: types.APIVerbCreate,
  486. Method: types.HTTPVerbPost,
  487. Path: &types.Path{
  488. Parent: basePath,
  489. RelativePath: fmt.Sprintf("/stacks/{%s}/events", types.URLParamPorterAppName),
  490. },
  491. Scopes: []types.PermissionScope{
  492. types.UserScope,
  493. types.ProjectScope,
  494. types.ClusterScope,
  495. },
  496. },
  497. )
  498. LEGACY_createPorterAppEventHandler := porter_app.NewCreateUpdatePorterAppEventHandler(
  499. config,
  500. factory.GetDecoderValidator(),
  501. factory.GetResultWriter(),
  502. )
  503. routes = append(routes, &router.Route{
  504. Endpoint: LEGACY_createPorterAppEventEndpoint,
  505. Handler: LEGACY_createPorterAppEventHandler,
  506. Router: r,
  507. })
  508. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/parse -> porter_app.NewParsePorterYAMLToProtoHandler
  509. parsePorterYAMLToProtoEndpoint := factory.NewAPIEndpoint(
  510. &types.APIRequestMetadata{
  511. Verb: types.APIVerbGet,
  512. Method: types.HTTPVerbPost,
  513. Path: &types.Path{
  514. Parent: basePath,
  515. RelativePath: "/apps/parse",
  516. },
  517. Scopes: []types.PermissionScope{
  518. types.UserScope,
  519. types.ProjectScope,
  520. types.ClusterScope,
  521. },
  522. },
  523. )
  524. parsePorterYAMLToProtoHandler := porter_app.NewParsePorterYAMLToProtoHandler(
  525. config,
  526. factory.GetDecoderValidator(),
  527. factory.GetResultWriter(),
  528. )
  529. routes = append(routes, &router.Route{
  530. Endpoint: parsePorterYAMLToProtoEndpoint,
  531. Handler: parsePorterYAMLToProtoHandler,
  532. Router: r,
  533. })
  534. // POST /api/projects/{project_id}/clusters/{cluster_id}/apps/validate -> porter_app.NewValidatePorterAppHandler
  535. validatePorterAppEndpoint := factory.NewAPIEndpoint(
  536. &types.APIRequestMetadata{
  537. Verb: types.APIVerbGet,
  538. Method: types.HTTPVerbPost,
  539. Path: &types.Path{
  540. Parent: basePath,
  541. RelativePath: "/apps/validate",
  542. },
  543. Scopes: []types.PermissionScope{
  544. types.UserScope,
  545. types.ProjectScope,
  546. types.ClusterScope,
  547. },
  548. },
  549. )
  550. validatePorterAppHandler := porter_app.NewValidatePorterAppHandler(
  551. config,
  552. factory.GetDecoderValidator(),
  553. factory.GetResultWriter(),
  554. )
  555. routes = append(routes, &router.Route{
  556. Endpoint: validatePorterAppEndpoint,
  557. Handler: validatePorterAppHandler,
  558. Router: r,
  559. })
  560. // POST /api/projects/{project_id}/clusters/{cluster_id}/apps/create -> porter_app.NewCreateAppHandler
  561. createAppEndpoint := factory.NewAPIEndpoint(
  562. &types.APIRequestMetadata{
  563. Verb: types.APIVerbCreate,
  564. Method: types.HTTPVerbPost,
  565. Path: &types.Path{
  566. Parent: basePath,
  567. RelativePath: "/apps/create",
  568. },
  569. Scopes: []types.PermissionScope{
  570. types.UserScope,
  571. types.ProjectScope,
  572. types.ClusterScope,
  573. },
  574. },
  575. )
  576. createAppHandler := porter_app.NewCreateAppHandler(
  577. config,
  578. factory.GetDecoderValidator(),
  579. factory.GetResultWriter(),
  580. )
  581. routes = append(routes, &router.Route{
  582. Endpoint: createAppEndpoint,
  583. Handler: createAppHandler,
  584. Router: r,
  585. })
  586. // POST /api/projects/{project_id}/clusters/{cluster_id}/apps/apply -> porter_app.NewApplyPorterAppHandler
  587. applyPorterAppEndpoint := factory.NewAPIEndpoint(
  588. &types.APIRequestMetadata{
  589. Verb: types.APIVerbUpdate,
  590. Method: types.HTTPVerbPost,
  591. Path: &types.Path{
  592. Parent: basePath,
  593. RelativePath: "/apps/apply",
  594. },
  595. Scopes: []types.PermissionScope{
  596. types.UserScope,
  597. types.ProjectScope,
  598. types.ClusterScope,
  599. },
  600. },
  601. )
  602. applyPorterAppHandler := porter_app.NewApplyPorterAppHandler(
  603. config,
  604. factory.GetDecoderValidator(),
  605. factory.GetResultWriter(),
  606. )
  607. routes = append(routes, &router.Route{
  608. Endpoint: applyPorterAppEndpoint,
  609. Handler: applyPorterAppHandler,
  610. Router: r,
  611. })
  612. // GET /api/projects/{project_id}/clusters/{cluster_id}/default-deployment-target -> porter_app.NewDefaultDeploymentTargetHandler
  613. defaultDeploymentTargetEndpoint := factory.NewAPIEndpoint(
  614. &types.APIRequestMetadata{
  615. Verb: types.APIVerbGet,
  616. Method: types.HTTPVerbGet,
  617. Path: &types.Path{
  618. Parent: basePath,
  619. RelativePath: "/default-deployment-target",
  620. },
  621. Scopes: []types.PermissionScope{
  622. types.UserScope,
  623. types.ProjectScope,
  624. types.ClusterScope,
  625. },
  626. },
  627. )
  628. defaultDeploymentTargetHandler := porter_app.NewDefaultDeploymentTargetHandler(
  629. config,
  630. factory.GetDecoderValidator(),
  631. factory.GetResultWriter(),
  632. )
  633. routes = append(routes, &router.Route{
  634. Endpoint: defaultDeploymentTargetEndpoint,
  635. Handler: defaultDeploymentTargetHandler,
  636. Router: r,
  637. })
  638. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/latest -> porter_app.NewCurrentAppRevisionHandler
  639. currentAppRevisionEndpoint := factory.NewAPIEndpoint(
  640. &types.APIRequestMetadata{
  641. Verb: types.APIVerbGet,
  642. Method: types.HTTPVerbGet,
  643. Path: &types.Path{
  644. Parent: basePath,
  645. RelativePath: fmt.Sprintf("/apps/{%s}/latest", types.URLParamPorterAppName),
  646. },
  647. Scopes: []types.PermissionScope{
  648. types.UserScope,
  649. types.ProjectScope,
  650. types.ClusterScope,
  651. },
  652. },
  653. )
  654. currentAppRevisionHandler := porter_app.NewLatestAppRevisionHandler(
  655. config,
  656. factory.GetDecoderValidator(),
  657. factory.GetResultWriter(),
  658. )
  659. routes = append(routes, &router.Route{
  660. Endpoint: currentAppRevisionEndpoint,
  661. Handler: currentAppRevisionHandler,
  662. Router: r,
  663. })
  664. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/revisions -> porter_app.NewCurrentAppRevisionHandler
  665. listAppRevisionsEndpoint := factory.NewAPIEndpoint(
  666. &types.APIRequestMetadata{
  667. Verb: types.APIVerbGet,
  668. Method: types.HTTPVerbGet,
  669. Path: &types.Path{
  670. Parent: basePath,
  671. RelativePath: fmt.Sprintf("/apps/{%s}/revisions", types.URLParamPorterAppName),
  672. },
  673. Scopes: []types.PermissionScope{
  674. types.UserScope,
  675. types.ProjectScope,
  676. types.ClusterScope,
  677. },
  678. },
  679. )
  680. listAppRevisionsHandler := porter_app.NewListAppRevisionsHandler(
  681. config,
  682. factory.GetDecoderValidator(),
  683. factory.GetResultWriter(),
  684. )
  685. routes = append(routes, &router.Route{
  686. Endpoint: listAppRevisionsEndpoint,
  687. Handler: listAppRevisionsHandler,
  688. Router: r,
  689. })
  690. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/revisions -> porter_app.NewCurrentAppRevisionHandler
  691. latestAppRevisionsEndpoint := factory.NewAPIEndpoint(
  692. &types.APIRequestMetadata{
  693. Verb: types.APIVerbGet,
  694. Method: types.HTTPVerbGet,
  695. Path: &types.Path{
  696. Parent: basePath,
  697. RelativePath: "/apps/revisions",
  698. },
  699. Scopes: []types.PermissionScope{
  700. types.UserScope,
  701. types.ProjectScope,
  702. types.ClusterScope,
  703. },
  704. },
  705. )
  706. latestAppRevisionsHandler := porter_app.NewLatestAppRevisionsHandler(
  707. config,
  708. factory.GetDecoderValidator(),
  709. factory.GetResultWriter(),
  710. )
  711. routes = append(routes, &router.Route{
  712. Endpoint: latestAppRevisionsEndpoint,
  713. Handler: latestAppRevisionsHandler,
  714. Router: r,
  715. })
  716. // POST /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/subdomain -> porter_app.NewCreateSubdomainHandler
  717. createSubdomainEndpoint := factory.NewAPIEndpoint(
  718. &types.APIRequestMetadata{
  719. Verb: types.APIVerbUpdate,
  720. Method: types.HTTPVerbPost,
  721. Path: &types.Path{
  722. Parent: basePath,
  723. RelativePath: fmt.Sprintf("/apps/{%s}/subdomain", types.URLParamPorterAppName),
  724. },
  725. Scopes: []types.PermissionScope{
  726. types.UserScope,
  727. types.ProjectScope,
  728. types.ClusterScope,
  729. },
  730. },
  731. )
  732. createSubdomainHandler := porter_app.NewCreateSubdomainHandler(
  733. config,
  734. factory.GetDecoderValidator(),
  735. factory.GetResultWriter(),
  736. )
  737. routes = append(routes, &router.Route{
  738. Endpoint: createSubdomainEndpoint,
  739. Handler: createSubdomainHandler,
  740. Router: r,
  741. })
  742. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/{app_revision_id}/predeploy-status -> porter_app.NewPredeployStatusHandler
  743. predeployStatusEndpoint := factory.NewAPIEndpoint(
  744. &types.APIRequestMetadata{
  745. Verb: types.APIVerbGet,
  746. Method: types.HTTPVerbGet,
  747. Path: &types.Path{
  748. Parent: basePath,
  749. RelativePath: fmt.Sprintf("/apps/{%s}/{%s}/predeploy-status", types.URLParamPorterAppName, types.URLParamAppRevisionID),
  750. },
  751. Scopes: []types.PermissionScope{
  752. types.UserScope,
  753. types.ProjectScope,
  754. types.ClusterScope,
  755. },
  756. },
  757. )
  758. predeployStatusHandler := porter_app.NewPredeployStatusHandler(
  759. config,
  760. factory.GetDecoderValidator(),
  761. factory.GetResultWriter(),
  762. )
  763. routes = append(routes, &router.Route{
  764. Endpoint: predeployStatusEndpoint,
  765. Handler: predeployStatusHandler,
  766. Router: r,
  767. })
  768. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/logs -> cluster.NewAppLogsHandler
  769. appLogsEndpoint := factory.NewAPIEndpoint(
  770. &types.APIRequestMetadata{
  771. Verb: types.APIVerbGet,
  772. Method: types.HTTPVerbGet,
  773. Path: &types.Path{
  774. Parent: basePath,
  775. RelativePath: "/apps/logs",
  776. },
  777. Scopes: []types.PermissionScope{
  778. types.UserScope,
  779. types.ProjectScope,
  780. types.ClusterScope,
  781. },
  782. },
  783. )
  784. appLogsHandler := porter_app.NewAppLogsHandler(
  785. config,
  786. factory.GetDecoderValidator(),
  787. factory.GetResultWriter(),
  788. )
  789. routes = append(routes, &router.Route{
  790. Endpoint: appLogsEndpoint,
  791. Handler: appLogsHandler,
  792. Router: r,
  793. })
  794. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/logs/loki -> namespace.NewStreamLogsLokiHandler
  795. streamLogsLokiEndpoint := factory.NewAPIEndpoint(
  796. &types.APIRequestMetadata{
  797. Verb: types.APIVerbGet,
  798. Method: types.HTTPVerbGet,
  799. Path: &types.Path{
  800. Parent: basePath,
  801. RelativePath: "/apps/logs/loki",
  802. },
  803. Scopes: []types.PermissionScope{
  804. types.UserScope,
  805. types.ProjectScope,
  806. types.ClusterScope,
  807. },
  808. IsWebsocket: true,
  809. },
  810. )
  811. streamLogsLokiHandler := porter_app.NewStreamLogsLokiHandler(
  812. config,
  813. factory.GetDecoderValidator(),
  814. factory.GetResultWriter(),
  815. )
  816. routes = append(routes, &router.Route{
  817. Endpoint: streamLogsLokiEndpoint,
  818. Handler: streamLogsLokiHandler,
  819. Router: r,
  820. })
  821. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/metrics -> cluster.NewGetPodMetricsHandler
  822. appMetricsEndpoint := factory.NewAPIEndpoint(
  823. &types.APIRequestMetadata{
  824. Verb: types.APIVerbGet,
  825. Method: types.HTTPVerbGet,
  826. Path: &types.Path{
  827. Parent: basePath,
  828. RelativePath: "/apps/metrics",
  829. },
  830. Scopes: []types.PermissionScope{
  831. types.UserScope,
  832. types.ProjectScope,
  833. types.ClusterScope,
  834. },
  835. },
  836. )
  837. appMetricsHandler := porter_app.NewAppMetricsHandler(
  838. config,
  839. factory.GetDecoderValidator(),
  840. factory.GetResultWriter(),
  841. )
  842. routes = append(routes, &router.Route{
  843. Endpoint: appMetricsEndpoint,
  844. Handler: appMetricsHandler,
  845. Router: r,
  846. })
  847. // POST /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/revisions/{app_revision_id} -> porter_app.NewUpdateAppRevisionStatusHandler
  848. updateAppRevisionStatusEndpoint := factory.NewAPIEndpoint(
  849. &types.APIRequestMetadata{
  850. Verb: types.APIVerbUpdate,
  851. Method: types.HTTPVerbPost,
  852. Path: &types.Path{
  853. Parent: basePath,
  854. RelativePath: fmt.Sprintf("/apps/{%s}/revisions/{%s}", types.URLParamPorterAppName, types.URLParamAppRevisionID),
  855. },
  856. Scopes: []types.PermissionScope{
  857. types.UserScope,
  858. types.ProjectScope,
  859. types.ClusterScope,
  860. },
  861. },
  862. )
  863. updateAppRevisionStatusHandler := porter_app.NewUpdateAppRevisionStatusHandler(
  864. config,
  865. factory.GetDecoderValidator(),
  866. factory.GetResultWriter(),
  867. )
  868. routes = append(routes, &router.Route{
  869. Endpoint: updateAppRevisionStatusEndpoint,
  870. Handler: updateAppRevisionStatusHandler,
  871. Router: r,
  872. })
  873. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/revisions/{app_revision_id}/build-env -> porter_app.NewGetBuildEnvHandler
  874. getBuildEnvEndpoint := factory.NewAPIEndpoint(
  875. &types.APIRequestMetadata{
  876. Verb: types.APIVerbGet,
  877. Method: types.HTTPVerbGet,
  878. Path: &types.Path{
  879. Parent: basePath,
  880. RelativePath: fmt.Sprintf("/apps/{%s}/revisions/{%s}/build-env", types.URLParamPorterAppName, types.URLParamAppRevisionID),
  881. },
  882. Scopes: []types.PermissionScope{
  883. types.UserScope,
  884. types.ProjectScope,
  885. types.ClusterScope,
  886. },
  887. },
  888. )
  889. getBuildEnvHandler := porter_app.NewGetBuildEnvHandler(
  890. config,
  891. factory.GetDecoderValidator(),
  892. factory.GetResultWriter(),
  893. )
  894. routes = append(routes, &router.Route{
  895. Endpoint: getBuildEnvEndpoint,
  896. Handler: getBuildEnvHandler,
  897. Router: r,
  898. })
  899. // POST /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/update-environment -> porter_app.NewUpdateAppEnvironmentHandler
  900. updateAppEnvironmentGroupEndpoint := factory.NewAPIEndpoint(
  901. &types.APIRequestMetadata{
  902. Verb: types.APIVerbUpdate,
  903. Method: types.HTTPVerbPost,
  904. Path: &types.Path{
  905. Parent: basePath,
  906. RelativePath: fmt.Sprintf("/apps/{%s}/update-environment", types.URLParamPorterAppName),
  907. },
  908. Scopes: []types.PermissionScope{
  909. types.UserScope,
  910. types.ProjectScope,
  911. types.ClusterScope,
  912. },
  913. },
  914. )
  915. updateAppEnvironmentGroupHandler := porter_app.NewUpdateAppEnvironmentHandler(
  916. config,
  917. factory.GetDecoderValidator(),
  918. factory.GetResultWriter(),
  919. )
  920. routes = append(routes, &router.Route{
  921. Endpoint: updateAppEnvironmentGroupEndpoint,
  922. Handler: updateAppEnvironmentGroupHandler,
  923. Router: r,
  924. })
  925. // GET /api/projects/{project_id}/clusters/{cluster_id}/apps/{porter_app_name}/revisions/{app_revision_id}/env -> porter_app.NewGetAppEnvHandler
  926. getAppEnvEndpoint := factory.NewAPIEndpoint(
  927. &types.APIRequestMetadata{
  928. Verb: types.APIVerbGet,
  929. Method: types.HTTPVerbGet,
  930. Path: &types.Path{
  931. Parent: basePath,
  932. RelativePath: fmt.Sprintf("/apps/{%s}/revisions/{%s}/env", types.URLParamPorterAppName, types.URLParamAppRevisionID),
  933. },
  934. Scopes: []types.PermissionScope{
  935. types.UserScope,
  936. types.ProjectScope,
  937. types.ClusterScope,
  938. },
  939. },
  940. )
  941. getAppEnvHandler := porter_app.NewGetAppEnvHandler(
  942. config,
  943. factory.GetDecoderValidator(),
  944. factory.GetResultWriter(),
  945. )
  946. routes = append(routes, &router.Route{
  947. Endpoint: getAppEnvEndpoint,
  948. Handler: getAppEnvHandler,
  949. Router: r,
  950. })
  951. return routes, newPath
  952. }