porter_app.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889
  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. // ValidatePorterAppInput is the input struct to ValidatePorterApp
  169. type ValidatePorterAppInput struct {
  170. ProjectID uint
  171. ClusterID uint
  172. AppName string
  173. Base64AppProto string
  174. Base64AppOverrides string
  175. DeploymentTarget string
  176. CommitSHA string
  177. ImageTagOverride string
  178. }
  179. // ValidatePorterApp takes in a base64 encoded app definition that is potentially partial and returns a complete definition
  180. // using any previous app revisions and defaults
  181. func (c *Client) ValidatePorterApp(
  182. ctx context.Context,
  183. inp ValidatePorterAppInput,
  184. ) (*porter_app.ValidatePorterAppResponse, error) {
  185. resp := &porter_app.ValidatePorterAppResponse{}
  186. req := &porter_app.ValidatePorterAppRequest{
  187. AppName: inp.AppName,
  188. Base64AppProto: inp.Base64AppProto,
  189. Base64AppOverrides: inp.Base64AppOverrides,
  190. DeploymentTargetId: inp.DeploymentTarget,
  191. CommitSHA: inp.CommitSHA,
  192. ImageTagOverride: inp.ImageTagOverride,
  193. }
  194. err := c.postRequest(
  195. fmt.Sprintf(
  196. "/projects/%d/clusters/%d/apps/validate",
  197. inp.ProjectID, inp.ClusterID,
  198. ),
  199. req,
  200. resp,
  201. )
  202. return resp, err
  203. }
  204. // ApplyPorterAppInput is the input struct to ApplyPorterApp
  205. type ApplyPorterAppInput struct {
  206. ProjectID uint
  207. ClusterID uint
  208. Base64AppProto string
  209. DeploymentTarget string
  210. AppRevisionID string
  211. ForceBuild bool
  212. Variables map[string]string
  213. Secrets map[string]string
  214. HardEnvUpdate bool
  215. }
  216. // ApplyPorterApp takes in a base64 encoded app definition and applies it to the cluster
  217. func (c *Client) ApplyPorterApp(
  218. ctx context.Context,
  219. inp ApplyPorterAppInput,
  220. ) (*porter_app.ApplyPorterAppResponse, error) {
  221. resp := &porter_app.ApplyPorterAppResponse{}
  222. req := &porter_app.ApplyPorterAppRequest{
  223. Base64AppProto: inp.Base64AppProto,
  224. DeploymentTargetId: inp.DeploymentTarget,
  225. AppRevisionID: inp.AppRevisionID,
  226. ForceBuild: inp.ForceBuild,
  227. Variables: inp.Variables,
  228. Secrets: inp.Secrets,
  229. HardEnvUpdate: inp.HardEnvUpdate,
  230. }
  231. err := c.postRequest(
  232. fmt.Sprintf(
  233. "/projects/%d/clusters/%d/apps/apply",
  234. inp.ProjectID, inp.ClusterID,
  235. ),
  236. req,
  237. resp,
  238. postRequestOpts{
  239. retryCount: 3,
  240. onlyRetry500: true,
  241. },
  242. )
  243. return resp, err
  244. }
  245. // UpdateAppInput is the input struct to UpdateApp
  246. type UpdateAppInput struct {
  247. ProjectID uint
  248. ClusterID uint
  249. Name string
  250. ImageTagOverride string
  251. GitSource porter_app.GitSource
  252. DeploymentTargetId string
  253. CommitSHA string
  254. AppRevisionID string
  255. Base64AppProto string
  256. Base64PorterYAML string
  257. IsEnvOverride bool
  258. WithPredeploy bool
  259. Exact bool
  260. }
  261. // UpdateApp updates a porter app
  262. func (c *Client) UpdateApp(
  263. ctx context.Context,
  264. inp UpdateAppInput,
  265. ) (*porter_app.UpdateAppResponse, error) {
  266. resp := &porter_app.UpdateAppResponse{}
  267. req := &porter_app.UpdateAppRequest{
  268. Name: inp.Name,
  269. GitSource: inp.GitSource,
  270. DeploymentTargetId: inp.DeploymentTargetId,
  271. CommitSHA: inp.CommitSHA,
  272. ImageTagOverride: inp.ImageTagOverride,
  273. AppRevisionID: inp.AppRevisionID,
  274. Base64AppProto: inp.Base64AppProto,
  275. Base64PorterYAML: inp.Base64PorterYAML,
  276. IsEnvOverride: inp.IsEnvOverride,
  277. WithPredeploy: inp.WithPredeploy,
  278. Exact: inp.Exact,
  279. }
  280. err := c.postRequest(
  281. fmt.Sprintf(
  282. "/projects/%d/clusters/%d/apps/update",
  283. inp.ProjectID, inp.ClusterID,
  284. ),
  285. req,
  286. resp,
  287. )
  288. return resp, err
  289. }
  290. // DefaultDeploymentTarget returns the default deployment target for a given project and cluster
  291. func (c *Client) DefaultDeploymentTarget(
  292. ctx context.Context,
  293. projectID, clusterID uint,
  294. ) (*porter_app.DefaultDeploymentTargetResponse, error) {
  295. resp := &porter_app.DefaultDeploymentTargetResponse{}
  296. req := &porter_app.DefaultDeploymentTargetRequest{}
  297. err := c.getRequest(
  298. fmt.Sprintf(
  299. "/projects/%d/clusters/%d/default-deployment-target",
  300. projectID, clusterID,
  301. ),
  302. req,
  303. resp,
  304. )
  305. return resp, err
  306. }
  307. // CurrentAppRevisionInput is the input struct to CurrentAppRevision
  308. type CurrentAppRevisionInput struct {
  309. ProjectID uint
  310. ClusterID uint
  311. AppName string
  312. // DeploymentTargetName is the name of the deployment target to get the current app revision for. One of this or DeploymentTargetID must be set.
  313. DeploymentTargetName string
  314. // DeploymentTargetID is the id of the deployment target to get the current app revision for. One of this or DeploymentTargetName must be set.
  315. DeploymentTargetID string
  316. }
  317. // CurrentAppRevision returns the currently deployed app revision for a given project, app name and deployment target
  318. func (c *Client) CurrentAppRevision(
  319. ctx context.Context,
  320. input CurrentAppRevisionInput,
  321. ) (*porter_app.LatestAppRevisionResponse, error) {
  322. resp := &porter_app.LatestAppRevisionResponse{}
  323. req := &porter_app.LatestAppRevisionRequest{
  324. DeploymentTargetName: input.DeploymentTargetName,
  325. DeploymentTargetID: input.DeploymentTargetID,
  326. }
  327. err := c.getRequest(
  328. fmt.Sprintf(
  329. "/projects/%d/clusters/%d/apps/%s/latest",
  330. input.ProjectID, input.ClusterID, input.AppName,
  331. ),
  332. req,
  333. resp,
  334. )
  335. return resp, err
  336. }
  337. // CreatePorterAppDBEntryInput is the input struct to CreatePorterAppDBEntry
  338. type CreatePorterAppDBEntryInput struct {
  339. AppName string
  340. GitRepoName string
  341. GitRepoID uint
  342. GitBranch string
  343. ImageRepository string
  344. PorterYamlPath string
  345. ImageTag string
  346. Local bool
  347. DeploymentTargetID string
  348. }
  349. // CreatePorterAppDBEntry creates an entry in the porter app
  350. func (c *Client) CreatePorterAppDBEntry(
  351. ctx context.Context,
  352. projectID uint, clusterID uint,
  353. inp CreatePorterAppDBEntryInput,
  354. ) error {
  355. var sourceType appInternal.SourceType
  356. var image *appInternal.Image
  357. if inp.Local {
  358. sourceType = appInternal.SourceType_Local
  359. }
  360. if inp.GitRepoName != "" {
  361. sourceType = appInternal.SourceType_Github
  362. }
  363. if inp.ImageRepository != "" {
  364. sourceType = appInternal.SourceType_DockerRegistry
  365. image = &appInternal.Image{
  366. Repository: inp.ImageRepository,
  367. Tag: inp.ImageTag,
  368. }
  369. }
  370. req := &porter_app.CreateAppRequest{
  371. Name: inp.AppName,
  372. SourceType: sourceType,
  373. GitSource: porter_app.GitSource{
  374. GitBranch: inp.GitBranch,
  375. GitRepoName: inp.GitRepoName,
  376. GitRepoID: inp.GitRepoID,
  377. },
  378. Image: image,
  379. PorterYamlPath: inp.PorterYamlPath,
  380. DeploymentTargetID: inp.DeploymentTargetID,
  381. }
  382. err := c.postRequest(
  383. fmt.Sprintf(
  384. "/projects/%d/clusters/%d/apps/create",
  385. projectID, clusterID,
  386. ),
  387. req,
  388. &types.PorterApp{},
  389. )
  390. return err
  391. }
  392. // CreateSubdomain returns a subdomain for a given service that point to the ingress-nginx service in the cluster
  393. func (c *Client) CreateSubdomain(
  394. ctx context.Context,
  395. projectID uint, clusterID uint,
  396. appName string, serviceName string,
  397. ) (*porter_app.CreateSubdomainResponse, error) {
  398. resp := &porter_app.CreateSubdomainResponse{}
  399. req := &porter_app.CreateSubdomainRequest{
  400. ServiceName: serviceName,
  401. }
  402. err := c.postRequest(
  403. fmt.Sprintf(
  404. "/projects/%d/clusters/%d/apps/%s/subdomain",
  405. projectID, clusterID, appName,
  406. ),
  407. req,
  408. resp,
  409. )
  410. return resp, err
  411. }
  412. // PredeployStatus checks the current status of a predeploy job for an app revision
  413. func (c *Client) PredeployStatus(
  414. ctx context.Context,
  415. projectID uint, clusterID uint,
  416. appName string, appRevisionId string,
  417. ) (*porter_app.PredeployStatusResponse, error) {
  418. resp := &porter_app.PredeployStatusResponse{}
  419. err := c.getRequest(
  420. fmt.Sprintf(
  421. "/projects/%d/clusters/%d/apps/%s/%s/predeploy-status",
  422. projectID, clusterID, appName, appRevisionId,
  423. ),
  424. nil,
  425. resp,
  426. )
  427. if resp.Status == "" {
  428. return nil, fmt.Errorf("no predeploy status found")
  429. }
  430. return resp, err
  431. }
  432. // GetRevision returns an app revision
  433. func (c *Client) GetRevision(
  434. ctx context.Context,
  435. projectID uint, clusterID uint,
  436. appName string, appRevisionId string,
  437. ) (*porter_app.GetAppRevisionResponse, error) {
  438. resp := &porter_app.GetAppRevisionResponse{}
  439. err := c.getRequest(
  440. fmt.Sprintf(
  441. "/projects/%d/clusters/%d/apps/%s/revisions/%s",
  442. projectID, clusterID, appName, appRevisionId,
  443. ),
  444. nil,
  445. resp,
  446. )
  447. return resp, err
  448. }
  449. // GetRevisionStatus returns the status of an app revision
  450. func (c *Client) GetRevisionStatus(
  451. ctx context.Context,
  452. projectID uint, clusterID uint,
  453. appName string, appRevisionId string,
  454. ) (*porter_app.GetAppRevisionStatusResponse, error) {
  455. resp := &porter_app.GetAppRevisionStatusResponse{}
  456. err := c.getRequest(
  457. fmt.Sprintf(
  458. "/projects/%d/clusters/%d/apps/%s/revisions/%s/status",
  459. projectID, clusterID, appName, appRevisionId,
  460. ),
  461. nil,
  462. resp,
  463. )
  464. return resp, err
  465. }
  466. // UpdateRevisionStatus updates the status of an app revision
  467. func (c *Client) UpdateRevisionStatus(
  468. ctx context.Context,
  469. projectID uint, clusterID uint,
  470. appName string, appRevisionId string,
  471. status models.AppRevisionStatus,
  472. ) (*porter_app.UpdateAppRevisionStatusResponse, error) {
  473. resp := &porter_app.UpdateAppRevisionStatusResponse{}
  474. req := &porter_app.UpdateAppRevisionStatusRequest{
  475. Status: status,
  476. }
  477. err := c.postRequest(
  478. fmt.Sprintf(
  479. "/projects/%d/clusters/%d/apps/%s/revisions/%s",
  480. projectID, clusterID, appName, appRevisionId,
  481. ),
  482. req,
  483. resp,
  484. )
  485. return resp, err
  486. }
  487. // GetBuildEnv returns the build environment for a given app proto
  488. func (c *Client) GetBuildEnv(
  489. ctx context.Context,
  490. projectID uint, clusterID uint,
  491. appName string, appRevisionId string,
  492. ) (*porter_app.GetBuildEnvResponse, error) {
  493. resp := &porter_app.GetBuildEnvResponse{}
  494. err := c.getRequest(
  495. fmt.Sprintf(
  496. "/projects/%d/clusters/%d/apps/%s/revisions/%s/build-env",
  497. projectID, clusterID, appName, appRevisionId,
  498. ),
  499. nil,
  500. resp,
  501. )
  502. return resp, err
  503. }
  504. // GetAppEnvVariables returns all env variables for a given app
  505. func (c *Client) GetAppEnvVariables(
  506. ctx context.Context,
  507. projectID uint, clusterID uint,
  508. appName string,
  509. ) (*porter_app.AppEnvVariablesResponse, error) {
  510. resp := &porter_app.AppEnvVariablesResponse{}
  511. req := &porter_app.AppEnvVariablesRequest{}
  512. err := c.getRequest(
  513. fmt.Sprintf(
  514. "/projects/%d/clusters/%d/apps/%s/env-variables",
  515. projectID, clusterID, appName,
  516. ),
  517. req,
  518. resp,
  519. )
  520. return resp, err
  521. }
  522. // GetBuildFromRevision returns the build environment for a given app proto
  523. func (c *Client) GetBuildFromRevision(
  524. ctx context.Context,
  525. projectID uint, clusterID uint,
  526. appName string, appRevisionId string,
  527. ) (*porter_app.GetBuildFromRevisionResponse, error) {
  528. resp := &porter_app.GetBuildFromRevisionResponse{}
  529. err := c.getRequest(
  530. fmt.Sprintf(
  531. "/projects/%d/clusters/%d/apps/%s/revisions/%s/build",
  532. projectID, clusterID, appName, appRevisionId,
  533. ),
  534. nil,
  535. resp,
  536. )
  537. return resp, err
  538. }
  539. // ReportRevisionStatusInput is the input struct to ReportRevisionStatus
  540. type ReportRevisionStatusInput struct {
  541. ProjectID uint
  542. ClusterID uint
  543. AppName string
  544. AppRevisionID string
  545. PRNumber int
  546. CommitSHA string
  547. }
  548. // ReportRevisionStatus reports the status of an app revision to external services
  549. func (c *Client) ReportRevisionStatus(
  550. ctx context.Context,
  551. inp ReportRevisionStatusInput,
  552. ) (*porter_app.ReportRevisionStatusResponse, error) {
  553. resp := &porter_app.ReportRevisionStatusResponse{}
  554. req := &porter_app.ReportRevisionStatusRequest{
  555. PRNumber: inp.PRNumber,
  556. CommitSHA: inp.CommitSHA,
  557. }
  558. err := c.postRequest(
  559. fmt.Sprintf(
  560. "/projects/%d/clusters/%d/apps/%s/revisions/%s/status",
  561. inp.ProjectID, inp.ClusterID, inp.AppName, inp.AppRevisionID,
  562. ),
  563. req,
  564. resp,
  565. )
  566. return resp, err
  567. }
  568. // CreateOrUpdateAppEnvironment updates the app environment group and creates it if it doesn't exist
  569. func (c *Client) CreateOrUpdateAppEnvironment(
  570. ctx context.Context,
  571. projectID uint, clusterID uint,
  572. appName string,
  573. deploymentTargetID string,
  574. variables map[string]string,
  575. secrets map[string]string,
  576. Base64AppProto string,
  577. ) (*porter_app.UpdateAppEnvironmentResponse, error) {
  578. resp := &porter_app.UpdateAppEnvironmentResponse{}
  579. req := &porter_app.UpdateAppEnvironmentRequest{
  580. DeploymentTargetID: deploymentTargetID,
  581. Variables: variables,
  582. Secrets: secrets,
  583. HardUpdate: false,
  584. Base64AppProto: Base64AppProto,
  585. }
  586. err := c.postRequest(
  587. fmt.Sprintf(
  588. "/projects/%d/clusters/%d/apps/%s/update-environment",
  589. projectID, clusterID, appName,
  590. ),
  591. req,
  592. resp,
  593. )
  594. return resp, err
  595. }
  596. // PorterYamlV2Pods gets all pods for a given deployment target id and app name
  597. func (c *Client) PorterYamlV2Pods(
  598. ctx context.Context,
  599. projectID, clusterID uint,
  600. porterAppName string,
  601. deploymentTargetName string,
  602. ) (*types.GetReleaseAllPodsResponse, error) {
  603. req := &porter_app.PodStatusRequest{
  604. DeploymentTargetName: deploymentTargetName,
  605. }
  606. resp := &types.GetReleaseAllPodsResponse{}
  607. err := c.getRequest(
  608. fmt.Sprintf(
  609. "/projects/%d/clusters/%d/apps/%s/pods",
  610. projectID, clusterID,
  611. porterAppName,
  612. ),
  613. req,
  614. resp,
  615. )
  616. return resp, err
  617. }
  618. // UpdateImage updates the image for a porter app (porter yaml v2 only)
  619. func (c *Client) UpdateImage(
  620. ctx context.Context,
  621. projectID, clusterID uint,
  622. appName, deploymentTargetName, tag string,
  623. ) (*porter_app.UpdateImageResponse, error) {
  624. req := &porter_app.UpdateImageRequest{
  625. Tag: tag,
  626. DeploymentTargetName: deploymentTargetName,
  627. }
  628. resp := &porter_app.UpdateImageResponse{}
  629. err := c.postRequest(
  630. fmt.Sprintf(
  631. "/projects/%d/clusters/%d/apps/%s/update-image",
  632. projectID, clusterID, appName,
  633. ),
  634. &req,
  635. resp,
  636. )
  637. return resp, err
  638. }
  639. // ListAppRevisions lists the last ten app revisions for a given app
  640. func (c *Client) ListAppRevisions(
  641. ctx context.Context,
  642. projectID, clusterID uint,
  643. appName string,
  644. deploymentTargetID string,
  645. ) (*porter_app.ListAppRevisionsResponse, error) {
  646. resp := &porter_app.ListAppRevisionsResponse{}
  647. req := &porter_app.ListAppRevisionsRequest{
  648. DeploymentTargetID: deploymentTargetID,
  649. }
  650. err := c.getRequest(
  651. fmt.Sprintf(
  652. "/projects/%d/clusters/%d/apps/%s/revisions",
  653. projectID, clusterID,
  654. appName,
  655. ),
  656. req,
  657. resp,
  658. )
  659. return resp, err
  660. }
  661. // RollbackRevision reverts an app to a previous revision
  662. func (c *Client) RollbackRevision(
  663. ctx context.Context,
  664. projectID, clusterID uint,
  665. appName string,
  666. deploymentTargetName string,
  667. ) (*porter_app.RollbackAppRevisionResponse, error) {
  668. resp := &porter_app.RollbackAppRevisionResponse{}
  669. req := &porter_app.RollbackAppRevisionRequest{
  670. DeploymentTargetName: deploymentTargetName,
  671. }
  672. err := c.postRequest(
  673. fmt.Sprintf(
  674. "/projects/%d/clusters/%d/apps/%s/rollback",
  675. projectID, clusterID,
  676. appName,
  677. ),
  678. req,
  679. resp,
  680. )
  681. return resp, err
  682. }
  683. // UseNewApplyLogic checks whether the CLI should use the new apply logic
  684. func (c *Client) UseNewApplyLogic(
  685. ctx context.Context,
  686. projectID, clusterID uint,
  687. ) (*porter_app.UseNewApplyLogicResponse, error) {
  688. resp := &porter_app.UseNewApplyLogicResponse{}
  689. req := &porter_app.UseNewApplyLogicRequest{}
  690. err := c.getRequest(
  691. fmt.Sprintf(
  692. "/projects/%d/clusters/%d/apps/use-new-apply-logic",
  693. projectID, clusterID,
  694. ),
  695. req,
  696. resp,
  697. )
  698. return resp, err
  699. }
  700. // RunAppJob runs a job for an app
  701. func (c *Client) RunAppJob(
  702. ctx context.Context,
  703. projectID, clusterID uint,
  704. appName string, jobName string,
  705. deploymentTargetName string,
  706. ) (*porter_app.RunAppJobResponse, error) {
  707. resp := &porter_app.RunAppJobResponse{}
  708. req := &porter_app.RunAppJobRequest{
  709. ServiceName: jobName,
  710. DeploymentTargetName: deploymentTargetName,
  711. }
  712. err := c.postRequest(
  713. fmt.Sprintf(
  714. "/projects/%d/clusters/%d/apps/%s/run",
  715. projectID, clusterID,
  716. appName,
  717. ),
  718. req,
  719. resp,
  720. )
  721. return resp, err
  722. }
  723. // RunAppJobStatusInput contains all the information necessary to check the status of a job
  724. type RunAppJobStatusInput struct {
  725. // AppName is the name of the app associated with the job
  726. AppName string
  727. // Cluster is the id of the cluster against which to retrieve a helm agent for
  728. ClusterID uint
  729. // DeploymentTargetName is the id of the deployment target the job was run against
  730. DeploymentTargetName string
  731. // ServiceName is the name of the app service that was triggered
  732. ServiceName string
  733. // JobRunID is the UID returned from the /apps/{porter_app_name}/run endpoint
  734. JobRunID string
  735. // ProjectID is the project in which the cluster exists
  736. ProjectID uint
  737. }
  738. // RunAppJobStatus gets the status for a job app run
  739. func (c *Client) RunAppJobStatus(
  740. ctx context.Context,
  741. input RunAppJobStatusInput,
  742. ) (*porter_app.AppJobRunStatusResponse, error) {
  743. resp := &porter_app.AppJobRunStatusResponse{}
  744. req := &porter_app.AppJobRunStatusRequest{
  745. DeploymentTargetName: input.DeploymentTargetName,
  746. JobRunID: input.JobRunID,
  747. ServiceName: input.ServiceName,
  748. }
  749. err := c.getRequest(
  750. fmt.Sprintf(
  751. "/projects/%d/clusters/%d/apps/%s/run-status",
  752. input.ProjectID, input.ClusterID,
  753. input.AppName,
  754. ),
  755. req,
  756. resp,
  757. )
  758. return resp, err
  759. }