gcp.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  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. // ------------------------------------------------------------------
  20. // All fields encrypted before storage.
  21. // ------------------------------------------------------------------
  22. // KeyData for a service account for GCP connectors
  23. GCPKeyData []byte `json:"gcp_key_data"`
  24. }
  25. // GCPIntegrationExternal is a GCPIntegration to be shared over REST
  26. type GCPIntegrationExternal struct {
  27. ID uint `json:"id"`
  28. // The id of the user that linked this auth mechanism
  29. UserID uint `json:"user_id"`
  30. // The project that this integration belongs to
  31. ProjectID uint `json:"project_id"`
  32. // The GCP project id where the service account for this auth mechanism persists
  33. GCPProjectID string `json:"gcp-project-id"`
  34. // The GCP user email that linked this service account
  35. GCPUserEmail string `json:"gcp-user-email"`
  36. }
  37. // Externalize generates an external KubeIntegration to be shared over REST
  38. func (g *GCPIntegration) Externalize() *GCPIntegrationExternal {
  39. return &GCPIntegrationExternal{
  40. ID: g.ID,
  41. UserID: g.UserID,
  42. ProjectID: g.ProjectID,
  43. GCPProjectID: g.GCPProjectID,
  44. GCPUserEmail: g.GCPUserEmail,
  45. }
  46. }
  47. // ToProjectIntegration converts a gcp integration to a project integration
  48. func (g *GCPIntegration) ToProjectIntegration(
  49. category string,
  50. service IntegrationService,
  51. ) *ProjectIntegration {
  52. return &ProjectIntegration{
  53. ID: g.ID,
  54. ProjectID: g.ProjectID,
  55. AuthMechanism: "gcp",
  56. Category: category,
  57. Service: service,
  58. }
  59. }
  60. // GetBearerToken retrieves a bearer token for a GCP account
  61. func (g *GCPIntegration) GetBearerToken(
  62. getTokenCache GetTokenCacheFunc,
  63. setTokenCache SetTokenCacheFunc,
  64. ) (string, error) {
  65. cache, err := getTokenCache()
  66. // check the token cache for a non-expired token
  67. if cache != nil {
  68. if tok := cache.Token; err == nil && !cache.IsExpired() && len(tok) > 0 {
  69. return string(tok), nil
  70. }
  71. }
  72. creds, err := google.CredentialsFromJSON(
  73. context.Background(),
  74. g.GCPKeyData,
  75. "https://www.googleapis.com/auth/cloud-platform",
  76. )
  77. if err != nil {
  78. return "", err
  79. }
  80. tok, err := creds.TokenSource.Token()
  81. if err != nil {
  82. return "", err
  83. }
  84. // update the token cache
  85. setTokenCache(tok.AccessToken, tok.Expiry)
  86. return tok.AccessToken, nil
  87. }