aws.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. package integrations
  2. import (
  3. "gorm.io/gorm"
  4. "github.com/aws/aws-sdk-go/aws"
  5. "github.com/aws/aws-sdk-go/aws/credentials"
  6. "github.com/aws/aws-sdk-go/aws/session"
  7. token "sigs.k8s.io/aws-iam-authenticator/pkg/token"
  8. )
  9. // AWSIntegration is an auth mechanism that uses a AWS IAM user to
  10. // authenticate
  11. type AWSIntegration struct {
  12. gorm.Model
  13. // The id of the user that linked this auth mechanism
  14. UserID uint `json:"user_id"`
  15. // The project that this integration belongs to
  16. ProjectID uint `json:"project_id"`
  17. // The AWS entity this is linked to (individual or organization)
  18. AWSEntityID string `json:"aws-entity-id"`
  19. // The AWS caller identity (ARN) which linked this service
  20. AWSCallerID string `json:"aws-caller-id"`
  21. // ------------------------------------------------------------------
  22. // All fields encrypted before storage.
  23. // ------------------------------------------------------------------
  24. // The AWS cluster ID
  25. // See https://github.com/kubernetes-sigs/aws-iam-authenticator#what-is-a-cluster-id
  26. AWSClusterID []byte `json:"aws_cluster_id"`
  27. // The AWS access key for this IAM user
  28. AWSAccessKeyID []byte `json:"aws_access_key_id"`
  29. // The AWS secret key for this IAM user
  30. AWSSecretAccessKey []byte `json:"aws_secret_access_key"`
  31. // An optional session token, if the user is assuming a role
  32. AWSSessionToken []byte `json:"aws_session_token"`
  33. }
  34. // AWSIntegrationExternal is a AWSIntegration to be shared over REST
  35. type AWSIntegrationExternal struct {
  36. ID uint `json:"id"`
  37. // The id of the user that linked this auth mechanism
  38. UserID uint `json:"user_id"`
  39. // The project that this integration belongs to
  40. ProjectID uint `json:"project_id"`
  41. // The AWS entity this is linked to (individual or organization)
  42. AWSEntityID string `json:"aws-entity-id"`
  43. // The AWS caller identity (ARN) which linked this service
  44. AWSCallerID string `json:"aws-caller-id"`
  45. }
  46. // Externalize generates an external KubeIntegration to be shared over REST
  47. func (a *AWSIntegration) Externalize() *AWSIntegrationExternal {
  48. return &AWSIntegrationExternal{
  49. ID: a.ID,
  50. UserID: a.UserID,
  51. ProjectID: a.ProjectID,
  52. AWSEntityID: a.AWSEntityID,
  53. AWSCallerID: a.AWSCallerID,
  54. }
  55. }
  56. // GetBearerToken retrieves a bearer token for an AWS account
  57. func (a *AWSIntegration) GetBearerToken(
  58. getTokenCache GetTokenCacheFunc,
  59. setTokenCache SetTokenCacheFunc,
  60. ) (string, error) {
  61. cache, err := getTokenCache()
  62. // check the token cache for a non-expired token
  63. if tok := cache.Token; err == nil && !cache.IsExpired() && len(tok) > 0 {
  64. return string(tok), nil
  65. }
  66. generator, err := token.NewGenerator(false, false)
  67. if err != nil {
  68. return "", err
  69. }
  70. sess, err := session.NewSessionWithOptions(session.Options{
  71. SharedConfigState: session.SharedConfigEnable,
  72. Config: aws.Config{
  73. Credentials: credentials.NewStaticCredentials(
  74. string(a.AWSAccessKeyID),
  75. string(a.AWSSecretAccessKey),
  76. string(a.AWSSessionToken),
  77. ),
  78. },
  79. })
  80. if err != nil {
  81. return "", err
  82. }
  83. tok, err := generator.GetWithOptions(&token.GetTokenOptions{
  84. Session: sess,
  85. ClusterID: string(a.AWSClusterID),
  86. })
  87. if err != nil {
  88. return "", err
  89. }
  90. setTokenCache(tok.Token, tok.Expiration)
  91. return tok.Token, nil
  92. }