porter_app.go 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  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/api/types"
  7. )
  8. func (c *Client) NewGetPorterApp(
  9. ctx context.Context,
  10. projectID, clusterID uint,
  11. appName string,
  12. ) (*types.PorterApp, error) {
  13. resp := &types.PorterApp{}
  14. err := c.getRequest(
  15. fmt.Sprintf(
  16. "/projects/%d/clusters/%d/applications/%s",
  17. projectID, clusterID, appName,
  18. ),
  19. nil,
  20. resp,
  21. )
  22. return resp, err
  23. }
  24. func (c *Client) NewCreatePorterApp(
  25. ctx context.Context,
  26. projectID, clusterID uint,
  27. appName string,
  28. req *types.CreatePorterAppRequest,
  29. ) (*types.PorterApp, error) {
  30. resp := &types.PorterApp{}
  31. err := c.postRequest(
  32. fmt.Sprintf(
  33. "/projects/%d/clusters/%d/applications/%s",
  34. projectID, clusterID, appName,
  35. ),
  36. req,
  37. resp,
  38. )
  39. return resp, err
  40. }
  41. // 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
  42. func (c *Client) NewCreateOrUpdatePorterAppEvent(
  43. ctx context.Context,
  44. projectID, clusterID uint,
  45. appName string,
  46. req *types.CreateOrUpdatePorterAppEventRequest,
  47. ) (types.PorterAppEvent, error) {
  48. resp := &types.PorterAppEvent{}
  49. err := c.postRequest(
  50. fmt.Sprintf(
  51. "/projects/%d/clusters/%d/applications/%s/events",
  52. projectID, clusterID, appName,
  53. ),
  54. req,
  55. resp,
  56. )
  57. return *resp, err
  58. }
  59. // TODO: remove these functions once they are no longer called (check telemetry)
  60. func (c *Client) GetPorterApp(
  61. ctx context.Context,
  62. projectID, clusterID uint,
  63. stackName string,
  64. ) (*types.PorterApp, error) {
  65. resp := &types.PorterApp{}
  66. err := c.getRequest(
  67. fmt.Sprintf(
  68. "/projects/%d/clusters/%d/stacks/%s",
  69. projectID, clusterID, stackName,
  70. ),
  71. nil,
  72. resp,
  73. )
  74. return resp, err
  75. }
  76. func (c *Client) CreatePorterApp(
  77. ctx context.Context,
  78. projectID, clusterID uint,
  79. name string,
  80. req *types.CreatePorterAppRequest,
  81. ) (*types.PorterApp, error) {
  82. resp := &types.PorterApp{}
  83. err := c.postRequest(
  84. fmt.Sprintf(
  85. "/projects/%d/clusters/%d/stacks/%s",
  86. projectID, clusterID, name,
  87. ),
  88. req,
  89. resp,
  90. )
  91. return resp, err
  92. }
  93. // 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
  94. func (c *Client) CreateOrUpdatePorterAppEvent(
  95. ctx context.Context,
  96. projectID, clusterID uint,
  97. name string,
  98. req *types.CreateOrUpdatePorterAppEventRequest,
  99. ) (types.PorterAppEvent, error) {
  100. resp := &types.PorterAppEvent{}
  101. err := c.postRequest(
  102. fmt.Sprintf(
  103. "/projects/%d/clusters/%d/stacks/%s/events",
  104. projectID, clusterID, name,
  105. ),
  106. req,
  107. resp,
  108. )
  109. return *resp, err
  110. }
  111. // ListEnvGroups (List all Env Groups for a given cluster)
  112. func (c *Client) ListEnvGroups(
  113. ctx context.Context,
  114. projectID, clusterID uint,
  115. ) (types.ListEnvironmentGroupsResponse, error) {
  116. resp := &types.ListEnvironmentGroupsResponse{}
  117. err := c.getRequest(
  118. fmt.Sprintf(
  119. "/projects/%d/clusters/%d/environment-groups",
  120. projectID, clusterID,
  121. ),
  122. nil,
  123. resp,
  124. )
  125. return *resp, err
  126. }
  127. // ParseYAML takes in a base64 encoded porter yaml and returns an app proto
  128. func (c *Client) ParseYAML(
  129. ctx context.Context,
  130. projectID, clusterID uint,
  131. b64Yaml string,
  132. ) (*porter_app.ParsePorterYAMLToProtoResponse, error) {
  133. resp := &porter_app.ParsePorterYAMLToProtoResponse{}
  134. req := &porter_app.ParsePorterYAMLToProtoRequest{
  135. B64Yaml: b64Yaml,
  136. }
  137. err := c.postRequest(
  138. fmt.Sprintf(
  139. "/projects/%d/clusters/%d/apps/parse",
  140. projectID, clusterID,
  141. ),
  142. req,
  143. resp,
  144. )
  145. return resp, err
  146. }
  147. // ValidatePorterApp takes in a base64 encoded app definition that is potentially partial and returns a complete definition
  148. // using any previous app revisions and defaults
  149. func (c *Client) ValidatePorterApp(
  150. ctx context.Context,
  151. projectID, clusterID uint,
  152. base64AppProto string,
  153. deploymentTarget string,
  154. commitSHA string,
  155. ) (*porter_app.ValidatePorterAppResponse, error) {
  156. resp := &porter_app.ValidatePorterAppResponse{}
  157. req := &porter_app.ValidatePorterAppRequest{
  158. Base64AppProto: base64AppProto,
  159. DeploymentTargetId: deploymentTarget,
  160. CommitSHA: commitSHA,
  161. }
  162. err := c.postRequest(
  163. fmt.Sprintf(
  164. "/projects/%d/clusters/%d/apps/validate",
  165. projectID, clusterID,
  166. ),
  167. req,
  168. resp,
  169. )
  170. return resp, err
  171. }
  172. // ApplyPorterApp takes in a base64 encoded app definition and applies it to the cluster
  173. func (c *Client) ApplyPorterApp(
  174. ctx context.Context,
  175. projectID, clusterID uint,
  176. base64AppProto string,
  177. deploymentTarget string,
  178. appRevisionID string,
  179. ) (*porter_app.ApplyPorterAppResponse, error) {
  180. resp := &porter_app.ApplyPorterAppResponse{}
  181. req := &porter_app.ApplyPorterAppRequest{
  182. Base64AppProto: base64AppProto,
  183. DeploymentTargetId: deploymentTarget,
  184. AppRevisionID: appRevisionID,
  185. }
  186. err := c.postRequest(
  187. fmt.Sprintf(
  188. "/projects/%d/clusters/%d/apps/apply",
  189. projectID, clusterID,
  190. ),
  191. req,
  192. resp,
  193. )
  194. return resp, err
  195. }
  196. // DefaultDeploymentTarget returns the default deployment target for a given project and cluster
  197. func (c *Client) DefaultDeploymentTarget(
  198. ctx context.Context,
  199. projectID, clusterID uint,
  200. ) (*porter_app.DefaultDeploymentTargetResponse, error) {
  201. resp := &porter_app.DefaultDeploymentTargetResponse{}
  202. req := &porter_app.DefaultDeploymentTargetRequest{}
  203. err := c.getRequest(
  204. fmt.Sprintf(
  205. "/projects/%d/clusters/%d/default-deployment-target",
  206. projectID, clusterID,
  207. ),
  208. req,
  209. resp,
  210. )
  211. return resp, err
  212. }
  213. // CurrentAppRevision returns the currently deployed app revision for a given project, app name and deployment target
  214. func (c *Client) CurrentAppRevision(
  215. ctx context.Context,
  216. projectID uint, clusterID uint,
  217. appName string, deploymentTarget string,
  218. ) (*porter_app.LatestAppRevisionResponse, error) {
  219. resp := &porter_app.LatestAppRevisionResponse{}
  220. req := &porter_app.LatestAppRevisionRequest{
  221. DeploymentTargetID: deploymentTarget,
  222. }
  223. err := c.getRequest(
  224. fmt.Sprintf(
  225. "/projects/%d/clusters/%d/apps/%s/latest",
  226. projectID, clusterID, appName,
  227. ),
  228. req,
  229. resp,
  230. )
  231. return resp, err
  232. }
  233. // CreatePorterAppDBEntryInput is the input struct to CreatePorterAppDBEntry
  234. type CreatePorterAppDBEntryInput struct {
  235. AppName string
  236. GitRepoName string
  237. GitRepoID uint
  238. GitBranch string
  239. ImageRepository string
  240. PorterYamlPath string
  241. ImageTag string
  242. Local bool
  243. }
  244. // CreatePorterAppDBEntry creates an entry in the porter app
  245. func (c *Client) CreatePorterAppDBEntry(
  246. ctx context.Context,
  247. projectID uint, clusterID uint,
  248. inp CreatePorterAppDBEntryInput,
  249. ) error {
  250. var sourceType porter_app.SourceType
  251. var image *porter_app.Image
  252. if inp.Local {
  253. sourceType = porter_app.SourceType_Local
  254. }
  255. if inp.GitRepoName != "" {
  256. sourceType = porter_app.SourceType_Github
  257. }
  258. if inp.ImageRepository != "" {
  259. sourceType = porter_app.SourceType_DockerRegistry
  260. image = &porter_app.Image{
  261. Repository: inp.ImageRepository,
  262. Tag: inp.ImageTag,
  263. }
  264. }
  265. if sourceType == "" {
  266. return fmt.Errorf("cannot determine source type")
  267. }
  268. req := &porter_app.CreateAppRequest{
  269. Name: inp.AppName,
  270. SourceType: sourceType,
  271. GitBranch: inp.GitBranch,
  272. GitRepoName: inp.GitRepoName,
  273. GitRepoID: inp.GitRepoID,
  274. PorterYamlPath: inp.PorterYamlPath,
  275. Image: image,
  276. }
  277. err := c.postRequest(
  278. fmt.Sprintf(
  279. "/projects/%d/clusters/%d/apps/create",
  280. projectID, clusterID,
  281. ),
  282. req,
  283. &types.PorterApp{},
  284. )
  285. return err
  286. }
  287. // CreateSubdomain returns a subdomain for a given service that point to the ingress-nginx service in the cluster
  288. func (c *Client) CreateSubdomain(
  289. ctx context.Context,
  290. projectID uint, clusterID uint,
  291. appName string, serviceName string,
  292. ) (*porter_app.CreateSubdomainResponse, error) {
  293. resp := &porter_app.CreateSubdomainResponse{}
  294. req := &porter_app.CreateSubdomainRequest{
  295. ServiceName: serviceName,
  296. }
  297. err := c.postRequest(
  298. fmt.Sprintf(
  299. "/projects/%d/clusters/%d/apps/%s/subdomain",
  300. projectID, clusterID, appName,
  301. ),
  302. req,
  303. resp,
  304. )
  305. return resp, err
  306. }
  307. // PredeployStatus checks the current status of a predeploy job for an app revision
  308. func (c *Client) PredeployStatus(
  309. ctx context.Context,
  310. projectID uint, clusterID uint,
  311. appName string, appRevisionId string,
  312. ) (*porter_app.PredeployStatusResponse, error) {
  313. resp := &porter_app.PredeployStatusResponse{}
  314. err := c.getRequest(
  315. fmt.Sprintf(
  316. "/projects/%d/clusters/%d/apps/%s/%s/predeploy-status",
  317. projectID, clusterID, appName, appRevisionId,
  318. ),
  319. nil,
  320. resp,
  321. )
  322. if resp.Status == "" {
  323. return nil, fmt.Errorf("no predeploy status found")
  324. }
  325. return resp, err
  326. }