gcp.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package integrations
  2. import (
  3. "context"
  4. "golang.org/x/oauth2/google"
  5. "gorm.io/gorm"
  6. )
  7. // GCPIntegration is an auth mechanism that uses a GCP service account to
  8. // authenticate
  9. type GCPIntegration struct {
  10. gorm.Model
  11. // The id of the user that linked this auth mechanism
  12. UserID uint `json:"user_id"`
  13. // The project that this integration belongs to
  14. ProjectID uint `json:"project_id"`
  15. // The GCP project id where the service account for this auth mechanism persists
  16. GCPProjectID string `json:"gcp_project_id"`
  17. // The GCP user email that linked this service account
  18. GCPUserEmail string `json:"gcp-user-email"`
  19. // The GCP region, which may or may not be used by the integration
  20. GCPRegion string `json:"gcp_region"`
  21. // ------------------------------------------------------------------
  22. // All fields encrypted before storage.
  23. // ------------------------------------------------------------------
  24. // KeyData for a service account for GCP connectors
  25. GCPKeyData []byte `json:"gcp_key_data"`
  26. }
  27. // GCPIntegrationExternal is a GCPIntegration to be shared over REST
  28. type GCPIntegrationExternal struct {
  29. ID uint `json:"id"`
  30. // The id of the user that linked this auth mechanism
  31. UserID uint `json:"user_id"`
  32. // The project that this integration belongs to
  33. ProjectID uint `json:"project_id"`
  34. // The GCP project id where the service account for this auth mechanism persists
  35. GCPProjectID string `json:"gcp-project-id"`
  36. // The GCP user email that linked this service account
  37. GCPUserEmail string `json:"gcp-user-email"`
  38. }
  39. // Externalize generates an external KubeIntegration to be shared over REST
  40. func (g *GCPIntegration) Externalize() *GCPIntegrationExternal {
  41. return &GCPIntegrationExternal{
  42. ID: g.ID,
  43. UserID: g.UserID,
  44. ProjectID: g.ProjectID,
  45. GCPProjectID: g.GCPProjectID,
  46. GCPUserEmail: g.GCPUserEmail,
  47. }
  48. }
  49. // ToProjectIntegration converts a gcp integration to a project integration
  50. func (g *GCPIntegration) ToProjectIntegration(
  51. category string,
  52. service IntegrationService,
  53. ) *ProjectIntegration {
  54. return &ProjectIntegration{
  55. ID: g.ID,
  56. ProjectID: g.ProjectID,
  57. AuthMechanism: "gcp",
  58. Category: category,
  59. Service: service,
  60. }
  61. }
  62. // GetBearerToken retrieves a bearer token for a GCP account
  63. func (g *GCPIntegration) GetBearerToken(
  64. getTokenCache GetTokenCacheFunc,
  65. setTokenCache SetTokenCacheFunc,
  66. ) (string, error) {
  67. cache, err := getTokenCache()
  68. // check the token cache for a non-expired token
  69. if cache != nil {
  70. if tok := cache.Token; err == nil && !cache.IsExpired() && len(tok) > 0 {
  71. return string(tok), nil
  72. }
  73. }
  74. creds, err := google.CredentialsFromJSON(
  75. context.Background(),
  76. g.GCPKeyData,
  77. "https://www.googleapis.com/auth/cloud-platform",
  78. )
  79. if err != nil {
  80. return "", err
  81. }
  82. tok, err := creds.TokenSource.Token()
  83. if err != nil {
  84. return "", err
  85. }
  86. // update the token cache
  87. setTokenCache(tok.AccessToken, tok.Expiry)
  88. return tok.AccessToken, nil
  89. }