cluster.go 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. package models
  2. import (
  3. "encoding/json"
  4. "github.com/porter-dev/porter/api/types"
  5. "github.com/porter-dev/porter/internal/models/integrations"
  6. "gorm.io/gorm"
  7. )
  8. // ClusterAuth is an auth mechanism that a cluster candidate can resolve
  9. type ClusterAuth string
  10. // The support cluster candidate auth mechanisms
  11. const (
  12. X509 ClusterAuth = "x509"
  13. Basic ClusterAuth = "basic"
  14. Bearer ClusterAuth = "bearerToken"
  15. OIDC ClusterAuth = "oidc"
  16. GCP ClusterAuth = "gcp-sa"
  17. AWS ClusterAuth = "aws-sa"
  18. DO ClusterAuth = "do-oauth"
  19. Local ClusterAuth = "local"
  20. )
  21. // Cluster is an integration that can connect to a Kubernetes cluster via
  22. // a specific auth mechanism
  23. type Cluster struct {
  24. gorm.Model
  25. // The auth mechanism that this cluster will use
  26. AuthMechanism ClusterAuth `json:"auth_mechanism"`
  27. // The project that this integration belongs to
  28. ProjectID uint `json:"project_id"`
  29. // Name of the cluster
  30. Name string `json:"name"`
  31. // Server endpoint for the cluster
  32. Server string `json:"server"`
  33. // Additional fields optionally used by the kube client
  34. ClusterLocationOfOrigin string `json:"location_of_origin,omitempty"`
  35. TLSServerName string `json:"tls-server-name,omitempty"`
  36. InsecureSkipTLSVerify bool `json:"insecure-skip-tls-verify,omitempty"`
  37. ProxyURL string `json:"proxy-url,omitempty"`
  38. UserLocationOfOrigin string
  39. UserImpersonate string `json:"act-as,omitempty"`
  40. UserImpersonateGroups string `json:"act-as-groups,omitempty"`
  41. InfraID uint `json:"infra_id"`
  42. NotificationsDisabled bool `json:"notifications_disabled"`
  43. // ------------------------------------------------------------------
  44. // All fields below this line are encrypted before storage
  45. // ------------------------------------------------------------------
  46. // The various auth mechanisms available to the integration
  47. KubeIntegrationID uint
  48. OIDCIntegrationID uint
  49. GCPIntegrationID uint
  50. AWSIntegrationID uint
  51. DOIntegrationID uint
  52. // A token cache that can be used by an auth mechanism, if desired
  53. TokenCache integrations.ClusterTokenCache `json:"token_cache" gorm:"-" sql:"-"`
  54. TokenCacheID uint `gorm:"token_cache_id"`
  55. // CertificateAuthorityData for the cluster, encrypted at rest
  56. CertificateAuthorityData []byte `json:"certificate-authority-data,omitempty"`
  57. }
  58. // ToProjectType generates an external types.Project to be shared over REST
  59. func (c *Cluster) ToClusterType() *types.Cluster {
  60. serv := types.Kube
  61. if c.AWSIntegrationID != 0 {
  62. serv = types.EKS
  63. } else if c.GCPIntegrationID != 0 {
  64. serv = types.GKE
  65. } else if c.DOIntegrationID != 0 {
  66. serv = types.DOKS
  67. }
  68. return &types.Cluster{
  69. ID: c.ID,
  70. ProjectID: c.ProjectID,
  71. Name: c.Name,
  72. Server: c.Server,
  73. Service: serv,
  74. InfraID: c.InfraID,
  75. AWSIntegrationID: c.AWSIntegrationID,
  76. }
  77. }
  78. // ClusterCandidate is a cluster integration that requires additional action
  79. // from the user to set up.
  80. type ClusterCandidate struct {
  81. gorm.Model
  82. // The auth mechanism that this candidate will parse for
  83. AuthMechanism ClusterAuth `json:"auth_mechanism"`
  84. // The project that this integration belongs to
  85. ProjectID uint `json:"project_id"`
  86. // CreatedClusterID is the ID of the cluster that's eventually
  87. // created
  88. CreatedClusterID uint `json:"created_cluster_id"`
  89. // Resolvers are the list of resolvers: once all resolvers are "resolved," the
  90. // cluster will be created
  91. Resolvers []ClusterResolver `json:"resolvers"`
  92. // Name of the cluster
  93. Name string `json:"name"`
  94. // Server endpoint for the cluster
  95. Server string `json:"server"`
  96. // Name of the context that this was created from, if it exists
  97. ContextName string `json:"context_name"`
  98. // ------------------------------------------------------------------
  99. // All fields below this line are encrypted before storage
  100. // ------------------------------------------------------------------
  101. // The best-guess for the AWSClusterID, which is required by aws auth mechanisms
  102. // See https://github.com/kubernetes-sigs/aws-iam-authenticator#what-is-a-cluster-id
  103. AWSClusterIDGuess []byte `json:"aws_cluster_id_guess"`
  104. // The raw kubeconfig
  105. Kubeconfig []byte `json:"kubeconfig"`
  106. }
  107. func (cc *ClusterCandidate) ToClusterCandidateType() *types.ClusterCandidate {
  108. resolvers := make([]types.ClusterResolver, 0)
  109. for _, resolver := range cc.Resolvers {
  110. resolvers = append(resolvers, *resolver.ToClusterResolverType())
  111. }
  112. return &types.ClusterCandidate{
  113. ID: cc.ID,
  114. ProjectID: cc.ProjectID,
  115. CreatedClusterID: cc.CreatedClusterID,
  116. Name: cc.Name,
  117. Server: cc.Server,
  118. ContextName: cc.ContextName,
  119. Resolvers: resolvers,
  120. AWSClusterIDGuess: string(cc.AWSClusterIDGuess),
  121. }
  122. }
  123. // ClusterResolver is an action that must be resolved to set up
  124. // a Cluster
  125. type ClusterResolver struct {
  126. gorm.Model
  127. // The ClusterCandidate that this is resolving
  128. ClusterCandidateID uint `json:"cluster_candidate_id"`
  129. // One of the ClusterResolverNames
  130. Name types.ClusterResolverName `json:"name"`
  131. // Resolved is true if this has been resolved, false otherwise
  132. Resolved bool `json:"resolved"`
  133. // Data is additional data for resolving the action, for example a file name,
  134. // context name, etc
  135. Data []byte `json:"data,omitempty"`
  136. }
  137. func (cr *ClusterResolver) ToClusterResolverType() *types.ClusterResolver {
  138. info := types.ClusterResolverInfos[cr.Name]
  139. data := make(types.ClusterResolverData)
  140. json.Unmarshal(cr.Data, &data)
  141. return &types.ClusterResolver{
  142. ID: cr.ID,
  143. ClusterCandidateID: cr.ClusterCandidateID,
  144. Name: cr.Name,
  145. Resolved: cr.Resolved,
  146. Docs: info.Docs,
  147. Fields: info.Fields,
  148. Data: data,
  149. }
  150. }