porter_app.go 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760
  1. package client
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/porter-dev/porter/api/server/handlers/porter_app"
  6. "github.com/porter-dev/porter/internal/models"
  7. appInternal "github.com/porter-dev/porter/internal/porter_app"
  8. "github.com/porter-dev/porter/api/types"
  9. )
  10. func (c *Client) NewGetPorterApp(
  11. ctx context.Context,
  12. projectID, clusterID uint,
  13. appName string,
  14. ) (*types.PorterApp, error) {
  15. resp := &types.PorterApp{}
  16. err := c.getRequest(
  17. fmt.Sprintf(
  18. "/projects/%d/clusters/%d/applications/%s",
  19. projectID, clusterID, appName,
  20. ),
  21. nil,
  22. resp,
  23. )
  24. return resp, err
  25. }
  26. func (c *Client) NewCreatePorterApp(
  27. ctx context.Context,
  28. projectID, clusterID uint,
  29. appName string,
  30. req *types.CreatePorterAppRequest,
  31. ) (*types.PorterApp, error) {
  32. resp := &types.PorterApp{}
  33. err := c.postRequest(
  34. fmt.Sprintf(
  35. "/projects/%d/clusters/%d/applications/%s",
  36. projectID, clusterID, appName,
  37. ),
  38. req,
  39. resp,
  40. )
  41. return resp, err
  42. }
  43. // NewCreateOrUpdatePorterAppEvent will create a porter app event if one does not exist, or else it will update the existing one if an ID is passed in the object
  44. func (c *Client) NewCreateOrUpdatePorterAppEvent(
  45. ctx context.Context,
  46. projectID, clusterID uint,
  47. appName string,
  48. req *types.CreateOrUpdatePorterAppEventRequest,
  49. ) (types.PorterAppEvent, error) {
  50. resp := &types.PorterAppEvent{}
  51. err := c.postRequest(
  52. fmt.Sprintf(
  53. "/projects/%d/clusters/%d/applications/%s/events",
  54. projectID, clusterID, appName,
  55. ),
  56. req,
  57. resp,
  58. )
  59. return *resp, err
  60. }
  61. // TODO: remove these functions once they are no longer called (check telemetry)
  62. func (c *Client) GetPorterApp(
  63. ctx context.Context,
  64. projectID, clusterID uint,
  65. stackName string,
  66. ) (*types.PorterApp, error) {
  67. resp := &types.PorterApp{}
  68. err := c.getRequest(
  69. fmt.Sprintf(
  70. "/projects/%d/clusters/%d/stacks/%s",
  71. projectID, clusterID, stackName,
  72. ),
  73. nil,
  74. resp,
  75. )
  76. return resp, err
  77. }
  78. func (c *Client) CreatePorterApp(
  79. ctx context.Context,
  80. projectID, clusterID uint,
  81. name string,
  82. req *types.CreatePorterAppRequest,
  83. ) (*types.PorterApp, error) {
  84. resp := &types.PorterApp{}
  85. err := c.postRequest(
  86. fmt.Sprintf(
  87. "/projects/%d/clusters/%d/stacks/%s",
  88. projectID, clusterID, name,
  89. ),
  90. req,
  91. resp,
  92. )
  93. return resp, err
  94. }
  95. // CreateOrUpdatePorterAppEvent will create a porter app event if one does not exist, or else it will update the existing one if an ID is passed in the object
  96. func (c *Client) CreateOrUpdatePorterAppEvent(
  97. ctx context.Context,
  98. projectID, clusterID uint,
  99. name string,
  100. req *types.CreateOrUpdatePorterAppEventRequest,
  101. ) (types.PorterAppEvent, error) {
  102. resp := &types.PorterAppEvent{}
  103. err := c.postRequest(
  104. fmt.Sprintf(
  105. "/projects/%d/clusters/%d/stacks/%s/events",
  106. projectID, clusterID, name,
  107. ),
  108. req,
  109. resp,
  110. )
  111. return *resp, err
  112. }
  113. // ListEnvGroups (List all Env Groups for a given cluster)
  114. func (c *Client) ListEnvGroups(
  115. ctx context.Context,
  116. projectID, clusterID uint,
  117. ) (types.ListEnvironmentGroupsResponse, error) {
  118. resp := &types.ListEnvironmentGroupsResponse{}
  119. err := c.getRequest(
  120. fmt.Sprintf(
  121. "/projects/%d/clusters/%d/environment-groups",
  122. projectID, clusterID,
  123. ),
  124. nil,
  125. resp,
  126. )
  127. return *resp, err
  128. }
  129. // ParseYAML takes in a base64 encoded porter yaml and returns an app proto
  130. func (c *Client) ParseYAML(
  131. ctx context.Context,
  132. projectID, clusterID uint,
  133. b64Yaml string,
  134. appName string,
  135. ) (*porter_app.ParsePorterYAMLToProtoResponse, error) {
  136. resp := &porter_app.ParsePorterYAMLToProtoResponse{}
  137. req := &porter_app.ParsePorterYAMLToProtoRequest{
  138. B64Yaml: b64Yaml,
  139. AppName: appName,
  140. }
  141. err := c.postRequest(
  142. fmt.Sprintf(
  143. "/projects/%d/clusters/%d/apps/parse",
  144. projectID, clusterID,
  145. ),
  146. req,
  147. resp,
  148. )
  149. return resp, err
  150. }
  151. // GetAppManifests returns the manifests for a given app based on the latest successful app revision
  152. func (c *Client) GetAppManifests(
  153. ctx context.Context,
  154. projectID, clusterID uint,
  155. appName string,
  156. ) (*porter_app.AppManifestsResponse, error) {
  157. resp := &porter_app.AppManifestsResponse{}
  158. err := c.getRequest(
  159. fmt.Sprintf(
  160. "/projects/%d/clusters/%d/apps/%s/manifests",
  161. projectID, clusterID, appName,
  162. ),
  163. nil,
  164. resp,
  165. )
  166. return resp, err
  167. }
  168. // UpdateAppInput is the input struct to UpdateApp
  169. type UpdateAppInput struct {
  170. ProjectID uint
  171. ClusterID uint
  172. Name string
  173. ImageTagOverride string
  174. GitSource porter_app.GitSource
  175. DeploymentTargetId string
  176. DeploymentTargetName string
  177. CommitSHA string
  178. AppRevisionID string
  179. Base64AppProto string
  180. Base64PorterYAML string
  181. IsEnvOverride bool
  182. WithPredeploy bool
  183. Exact bool
  184. Variables map[string]string
  185. Secrets map[string]string
  186. Deletions porter_app.Deletions
  187. }
  188. // UpdateApp updates a porter app
  189. func (c *Client) UpdateApp(
  190. ctx context.Context,
  191. inp UpdateAppInput,
  192. ) (*porter_app.UpdateAppResponse, error) {
  193. resp := &porter_app.UpdateAppResponse{}
  194. req := &porter_app.UpdateAppRequest{
  195. Name: inp.Name,
  196. GitSource: inp.GitSource,
  197. DeploymentTargetId: inp.DeploymentTargetId,
  198. DeploymentTargetName: inp.DeploymentTargetName,
  199. CommitSHA: inp.CommitSHA,
  200. ImageTagOverride: inp.ImageTagOverride,
  201. AppRevisionID: inp.AppRevisionID,
  202. Base64AppProto: inp.Base64AppProto,
  203. Base64PorterYAML: inp.Base64PorterYAML,
  204. IsEnvOverride: inp.IsEnvOverride,
  205. WithPredeploy: inp.WithPredeploy,
  206. Exact: inp.Exact,
  207. Variables: inp.Variables,
  208. Secrets: inp.Secrets,
  209. Deletions: inp.Deletions,
  210. }
  211. err := c.postRequest(
  212. fmt.Sprintf(
  213. "/projects/%d/clusters/%d/apps/update",
  214. inp.ProjectID, inp.ClusterID,
  215. ),
  216. req,
  217. resp,
  218. )
  219. return resp, err
  220. }
  221. // DefaultDeploymentTarget returns the default deployment target for a given project and cluster
  222. func (c *Client) DefaultDeploymentTarget(
  223. ctx context.Context,
  224. projectID, clusterID uint,
  225. ) (*porter_app.DefaultDeploymentTargetResponse, error) {
  226. resp := &porter_app.DefaultDeploymentTargetResponse{}
  227. req := &porter_app.DefaultDeploymentTargetRequest{}
  228. err := c.getRequest(
  229. fmt.Sprintf(
  230. "/projects/%d/clusters/%d/default-deployment-target",
  231. projectID, clusterID,
  232. ),
  233. req,
  234. resp,
  235. )
  236. return resp, err
  237. }
  238. // CurrentAppRevisionInput is the input struct to CurrentAppRevision
  239. type CurrentAppRevisionInput struct {
  240. ProjectID uint
  241. ClusterID uint
  242. AppName string
  243. // DeploymentTargetName is the name of the deployment target to get the current app revision for. One of this or DeploymentTargetID must be set.
  244. DeploymentTargetName string
  245. // DeploymentTargetID is the id of the deployment target to get the current app revision for. One of this or DeploymentTargetName must be set.
  246. DeploymentTargetID string
  247. }
  248. // CurrentAppRevision returns the currently deployed app revision for a given project, app name and deployment target
  249. func (c *Client) CurrentAppRevision(
  250. ctx context.Context,
  251. input CurrentAppRevisionInput,
  252. ) (*porter_app.LatestAppRevisionResponse, error) {
  253. resp := &porter_app.LatestAppRevisionResponse{}
  254. req := &porter_app.LatestAppRevisionRequest{
  255. DeploymentTargetName: input.DeploymentTargetName,
  256. DeploymentTargetID: input.DeploymentTargetID,
  257. }
  258. err := c.getRequest(
  259. fmt.Sprintf(
  260. "/projects/%d/clusters/%d/apps/%s/latest",
  261. input.ProjectID, input.ClusterID, input.AppName,
  262. ),
  263. req,
  264. resp,
  265. )
  266. return resp, err
  267. }
  268. // CreatePorterAppDBEntryInput is the input struct to CreatePorterAppDBEntry
  269. type CreatePorterAppDBEntryInput struct {
  270. AppName string
  271. GitRepoName string
  272. GitRepoID uint
  273. GitBranch string
  274. ImageRepository string
  275. PorterYamlPath string
  276. ImageTag string
  277. Local bool
  278. DeploymentTargetID string
  279. }
  280. // CreatePorterAppDBEntry creates an entry in the porter app
  281. func (c *Client) CreatePorterAppDBEntry(
  282. ctx context.Context,
  283. projectID uint, clusterID uint,
  284. inp CreatePorterAppDBEntryInput,
  285. ) error {
  286. var sourceType appInternal.SourceType
  287. var image *appInternal.Image
  288. if inp.Local {
  289. sourceType = appInternal.SourceType_Local
  290. }
  291. if inp.GitRepoName != "" {
  292. sourceType = appInternal.SourceType_Github
  293. }
  294. if inp.ImageRepository != "" {
  295. sourceType = appInternal.SourceType_DockerRegistry
  296. image = &appInternal.Image{
  297. Repository: inp.ImageRepository,
  298. Tag: inp.ImageTag,
  299. }
  300. }
  301. req := &porter_app.CreateAppRequest{
  302. Name: inp.AppName,
  303. SourceType: sourceType,
  304. GitSource: porter_app.GitSource{
  305. GitBranch: inp.GitBranch,
  306. GitRepoName: inp.GitRepoName,
  307. GitRepoID: inp.GitRepoID,
  308. },
  309. Image: image,
  310. PorterYamlPath: inp.PorterYamlPath,
  311. DeploymentTargetID: inp.DeploymentTargetID,
  312. }
  313. err := c.postRequest(
  314. fmt.Sprintf(
  315. "/projects/%d/clusters/%d/apps/create",
  316. projectID, clusterID,
  317. ),
  318. req,
  319. &types.PorterApp{},
  320. )
  321. return err
  322. }
  323. // CreateSubdomain returns a subdomain for a given service that point to the ingress-nginx service in the cluster
  324. func (c *Client) CreateSubdomain(
  325. ctx context.Context,
  326. projectID uint, clusterID uint,
  327. appName string, serviceName string,
  328. ) (*porter_app.CreateSubdomainResponse, error) {
  329. resp := &porter_app.CreateSubdomainResponse{}
  330. req := &porter_app.CreateSubdomainRequest{
  331. ServiceName: serviceName,
  332. }
  333. err := c.postRequest(
  334. fmt.Sprintf(
  335. "/projects/%d/clusters/%d/apps/%s/subdomain",
  336. projectID, clusterID, appName,
  337. ),
  338. req,
  339. resp,
  340. )
  341. return resp, err
  342. }
  343. // PredeployStatus checks the current status of a predeploy job for an app revision
  344. func (c *Client) PredeployStatus(
  345. ctx context.Context,
  346. projectID uint, clusterID uint,
  347. appName string, appRevisionId string,
  348. ) (*porter_app.PredeployStatusResponse, error) {
  349. resp := &porter_app.PredeployStatusResponse{}
  350. err := c.getRequest(
  351. fmt.Sprintf(
  352. "/projects/%d/clusters/%d/apps/%s/%s/predeploy-status",
  353. projectID, clusterID, appName, appRevisionId,
  354. ),
  355. nil,
  356. resp,
  357. )
  358. if resp.Status == "" {
  359. return nil, fmt.Errorf("no predeploy status found")
  360. }
  361. return resp, err
  362. }
  363. // GetRevision returns an app revision
  364. func (c *Client) GetRevision(
  365. ctx context.Context,
  366. projectID uint, clusterID uint,
  367. appName string, appRevisionId string,
  368. ) (*porter_app.GetAppRevisionResponse, error) {
  369. resp := &porter_app.GetAppRevisionResponse{}
  370. err := c.getRequest(
  371. fmt.Sprintf(
  372. "/projects/%d/clusters/%d/apps/%s/revisions/%s",
  373. projectID, clusterID, appName, appRevisionId,
  374. ),
  375. nil,
  376. resp,
  377. )
  378. return resp, err
  379. }
  380. // GetRevisionStatus returns the status of an app revision
  381. func (c *Client) GetRevisionStatus(
  382. ctx context.Context,
  383. projectID uint, clusterID uint,
  384. appName string, appRevisionId string,
  385. ) (*porter_app.GetAppRevisionStatusResponse, error) {
  386. resp := &porter_app.GetAppRevisionStatusResponse{}
  387. err := c.getRequest(
  388. fmt.Sprintf(
  389. "/projects/%d/clusters/%d/apps/%s/revisions/%s/status",
  390. projectID, clusterID, appName, appRevisionId,
  391. ),
  392. nil,
  393. resp,
  394. )
  395. return resp, err
  396. }
  397. // UpdateRevisionStatus updates the status of an app revision
  398. func (c *Client) UpdateRevisionStatus(
  399. ctx context.Context,
  400. projectID uint, clusterID uint,
  401. appName string, appRevisionId string,
  402. status models.AppRevisionStatus,
  403. ) (*porter_app.UpdateAppRevisionStatusResponse, error) {
  404. resp := &porter_app.UpdateAppRevisionStatusResponse{}
  405. req := &porter_app.UpdateAppRevisionStatusRequest{
  406. Status: status,
  407. }
  408. err := c.postRequest(
  409. fmt.Sprintf(
  410. "/projects/%d/clusters/%d/apps/%s/revisions/%s",
  411. projectID, clusterID, appName, appRevisionId,
  412. ),
  413. req,
  414. resp,
  415. )
  416. return resp, err
  417. }
  418. // GetBuildEnv returns the build environment for a given app proto
  419. func (c *Client) GetBuildEnv(
  420. ctx context.Context,
  421. projectID uint, clusterID uint,
  422. appName string, appRevisionId string,
  423. ) (*porter_app.GetBuildEnvResponse, error) {
  424. resp := &porter_app.GetBuildEnvResponse{}
  425. err := c.getRequest(
  426. fmt.Sprintf(
  427. "/projects/%d/clusters/%d/apps/%s/revisions/%s/build-env",
  428. projectID, clusterID, appName, appRevisionId,
  429. ),
  430. nil,
  431. resp,
  432. )
  433. return resp, err
  434. }
  435. // GetAppEnvVariables returns all env variables for a given app
  436. func (c *Client) GetAppEnvVariables(
  437. ctx context.Context,
  438. projectID uint, clusterID uint,
  439. appName string,
  440. deploymentTargetName string,
  441. ) (*porter_app.AppEnvVariablesResponse, error) {
  442. resp := &porter_app.AppEnvVariablesResponse{}
  443. req := &porter_app.AppEnvVariablesRequest{
  444. DeploymentTargetName: deploymentTargetName,
  445. }
  446. err := c.getRequest(
  447. fmt.Sprintf(
  448. "/projects/%d/clusters/%d/apps/%s/env-variables",
  449. projectID, clusterID, appName,
  450. ),
  451. req,
  452. resp,
  453. )
  454. return resp, err
  455. }
  456. // GetBuildFromRevision returns the build environment for a given app proto
  457. func (c *Client) GetBuildFromRevision(
  458. ctx context.Context,
  459. projectID uint, clusterID uint,
  460. appName string, appRevisionId string,
  461. ) (*porter_app.GetBuildFromRevisionResponse, error) {
  462. resp := &porter_app.GetBuildFromRevisionResponse{}
  463. err := c.getRequest(
  464. fmt.Sprintf(
  465. "/projects/%d/clusters/%d/apps/%s/revisions/%s/build",
  466. projectID, clusterID, appName, appRevisionId,
  467. ),
  468. nil,
  469. resp,
  470. )
  471. return resp, err
  472. }
  473. // ReportRevisionStatusInput is the input struct to ReportRevisionStatus
  474. type ReportRevisionStatusInput struct {
  475. ProjectID uint
  476. ClusterID uint
  477. AppName string
  478. AppRevisionID string
  479. PRNumber int
  480. CommitSHA string
  481. }
  482. // ReportRevisionStatus reports the status of an app revision to external services
  483. func (c *Client) ReportRevisionStatus(
  484. ctx context.Context,
  485. inp ReportRevisionStatusInput,
  486. ) (*porter_app.ReportRevisionStatusResponse, error) {
  487. resp := &porter_app.ReportRevisionStatusResponse{}
  488. req := &porter_app.ReportRevisionStatusRequest{
  489. PRNumber: inp.PRNumber,
  490. CommitSHA: inp.CommitSHA,
  491. }
  492. err := c.postRequest(
  493. fmt.Sprintf(
  494. "/projects/%d/clusters/%d/apps/%s/revisions/%s/status",
  495. inp.ProjectID, inp.ClusterID, inp.AppName, inp.AppRevisionID,
  496. ),
  497. req,
  498. resp,
  499. )
  500. return resp, err
  501. }
  502. // PorterYamlV2Pods gets all pods for a given deployment target id and app name
  503. func (c *Client) PorterYamlV2Pods(
  504. ctx context.Context,
  505. projectID, clusterID uint,
  506. porterAppName string,
  507. deploymentTargetName string,
  508. ) (*types.GetReleaseAllPodsResponse, error) {
  509. req := &porter_app.PodStatusRequest{
  510. DeploymentTargetName: deploymentTargetName,
  511. }
  512. resp := &types.GetReleaseAllPodsResponse{}
  513. err := c.getRequest(
  514. fmt.Sprintf(
  515. "/projects/%d/clusters/%d/apps/%s/pods",
  516. projectID, clusterID,
  517. porterAppName,
  518. ),
  519. req,
  520. resp,
  521. )
  522. return resp, err
  523. }
  524. // UpdateImage updates the image for a porter app (porter yaml v2 only)
  525. func (c *Client) UpdateImage(
  526. ctx context.Context,
  527. projectID, clusterID uint,
  528. appName, deploymentTargetName, tag string,
  529. ) (*porter_app.UpdateImageResponse, error) {
  530. req := &porter_app.UpdateImageRequest{
  531. Tag: tag,
  532. DeploymentTargetName: deploymentTargetName,
  533. }
  534. resp := &porter_app.UpdateImageResponse{}
  535. err := c.postRequest(
  536. fmt.Sprintf(
  537. "/projects/%d/clusters/%d/apps/%s/update-image",
  538. projectID, clusterID, appName,
  539. ),
  540. &req,
  541. resp,
  542. )
  543. return resp, err
  544. }
  545. // ListAppRevisions lists the last ten app revisions for a given app
  546. func (c *Client) ListAppRevisions(
  547. ctx context.Context,
  548. projectID, clusterID uint,
  549. appName string,
  550. deploymentTargetID string,
  551. ) (*porter_app.ListAppRevisionsResponse, error) {
  552. resp := &porter_app.ListAppRevisionsResponse{}
  553. req := &porter_app.ListAppRevisionsRequest{
  554. DeploymentTargetID: deploymentTargetID,
  555. }
  556. err := c.getRequest(
  557. fmt.Sprintf(
  558. "/projects/%d/clusters/%d/apps/%s/revisions",
  559. projectID, clusterID,
  560. appName,
  561. ),
  562. req,
  563. resp,
  564. )
  565. return resp, err
  566. }
  567. // RollbackRevision reverts an app to a previous revision
  568. func (c *Client) RollbackRevision(
  569. ctx context.Context,
  570. projectID, clusterID uint,
  571. appName string,
  572. deploymentTargetName string,
  573. ) (*porter_app.RollbackAppRevisionResponse, error) {
  574. resp := &porter_app.RollbackAppRevisionResponse{}
  575. req := &porter_app.RollbackAppRevisionRequest{
  576. DeploymentTargetName: deploymentTargetName,
  577. }
  578. err := c.postRequest(
  579. fmt.Sprintf(
  580. "/projects/%d/clusters/%d/apps/%s/rollback",
  581. projectID, clusterID,
  582. appName,
  583. ),
  584. req,
  585. resp,
  586. )
  587. return resp, err
  588. }
  589. // RunAppJob runs a job for an app
  590. func (c *Client) RunAppJob(
  591. ctx context.Context,
  592. projectID, clusterID uint,
  593. appName string, jobName string,
  594. deploymentTargetName string,
  595. ) (*porter_app.RunAppJobResponse, error) {
  596. resp := &porter_app.RunAppJobResponse{}
  597. req := &porter_app.RunAppJobRequest{
  598. ServiceName: jobName,
  599. DeploymentTargetName: deploymentTargetName,
  600. }
  601. err := c.postRequest(
  602. fmt.Sprintf(
  603. "/projects/%d/clusters/%d/apps/%s/run",
  604. projectID, clusterID,
  605. appName,
  606. ),
  607. req,
  608. resp,
  609. )
  610. return resp, err
  611. }
  612. // RunAppJobStatusInput contains all the information necessary to check the status of a job
  613. type RunAppJobStatusInput struct {
  614. // AppName is the name of the app associated with the job
  615. AppName string
  616. // Cluster is the id of the cluster against which to retrieve a helm agent for
  617. ClusterID uint
  618. // DeploymentTargetName is the id of the deployment target the job was run against
  619. DeploymentTargetName string
  620. // ServiceName is the name of the app service that was triggered
  621. ServiceName string
  622. // JobRunID is the UID returned from the /apps/{porter_app_name}/run endpoint
  623. JobRunID string
  624. // ProjectID is the project in which the cluster exists
  625. ProjectID uint
  626. }
  627. // RunAppJobStatus gets the status for a job app run
  628. func (c *Client) RunAppJobStatus(
  629. ctx context.Context,
  630. input RunAppJobStatusInput,
  631. ) (*porter_app.AppJobRunStatusResponse, error) {
  632. resp := &porter_app.AppJobRunStatusResponse{}
  633. req := &porter_app.AppJobRunStatusRequest{
  634. DeploymentTargetName: input.DeploymentTargetName,
  635. JobRunID: input.JobRunID,
  636. ServiceName: input.ServiceName,
  637. }
  638. err := c.getRequest(
  639. fmt.Sprintf(
  640. "/projects/%d/clusters/%d/apps/%s/run-status",
  641. input.ProjectID, input.ClusterID,
  642. input.AppName,
  643. ),
  644. req,
  645. resp,
  646. )
  647. return resp, err
  648. }