kubeconfig.go 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. package kubernetes
  2. import (
  3. "github.com/porter-dev/porter/internal/models"
  4. "gopkg.in/yaml.v2"
  5. )
  6. // KubeConfigCluster represents the cluster field in a kubeconfig
  7. type KubeConfigCluster struct {
  8. Cluster struct {
  9. Server string `yaml:"server"`
  10. } `yaml:"cluster"`
  11. Name string `yaml:"name"`
  12. }
  13. // KubeConfigContext represents the context field in a kubeconfig
  14. type KubeConfigContext struct {
  15. Context struct {
  16. Cluster string `yaml:"cluster"`
  17. User string `yaml:"user"`
  18. } `yaml:"context"`
  19. Name string `yaml:"name"`
  20. }
  21. // KubeConfigUser represents the user field in a kubeconfig
  22. type KubeConfigUser struct {
  23. Name string `yaml:"name"`
  24. }
  25. // KubeConfig represents an unmarshaled kubeconfig
  26. type KubeConfig struct {
  27. CurrentContext string `yaml:"current-context"`
  28. Clusters []KubeConfigCluster `yaml:"clusters"`
  29. Contexts []KubeConfigContext `yaml:"contexts"`
  30. Users []KubeConfigUser `yaml:"users"`
  31. }
  32. // GetAllowedClusterConfigsFromBytes converts a raw string to a set of ClusterConfigs
  33. // by unmarshaling and calling (*KubeConfig).ToAllowedClusterConfigs
  34. func GetAllowedClusterConfigsFromBytes(bytes []byte, allowedClusters []string) ([]models.ClusterConfig, error) {
  35. conf := KubeConfig{}
  36. err := yaml.Unmarshal(bytes, &conf)
  37. if err != nil {
  38. return nil, err
  39. }
  40. clusters := conf.ToAllowedClusterConfigs(allowedClusters)
  41. return clusters, nil
  42. }
  43. // GetAllClusterConfigsFromBytes converts a raw string to a set of ClusterConfigs
  44. // by unmarshaling and calling (*KubeConfig).ToAllClusterConfigs
  45. func GetAllClusterConfigsFromBytes(bytes []byte) ([]models.ClusterConfig, error) {
  46. conf := KubeConfig{}
  47. err := yaml.Unmarshal(bytes, &conf)
  48. if err != nil {
  49. return nil, err
  50. }
  51. clusters := conf.ToAllClusterConfigs()
  52. return clusters, nil
  53. }
  54. // ToAllowedClusterConfigs converts a KubeConfig to a set of ClusterConfigs by
  55. // joining users and clusters on the context.
  56. //
  57. // It accepts a list of cluster names that the user wishes to connect to
  58. func (k *KubeConfig) ToAllowedClusterConfigs(allowedClusters []string) []models.ClusterConfig {
  59. clusters := make([]models.ClusterConfig, 0)
  60. // convert clusters, contexts, and users to maps for fast lookup
  61. clusterMap := k.createClusterMap()
  62. contextMap := k.createContextMap()
  63. userMap := k.createUserMap()
  64. // put allowed clusters in map
  65. aClusterMap := createAllowedClusterMap(allowedClusters)
  66. // iterate through context maps and link to a user-cluster pair
  67. for contextName, context := range contextMap {
  68. userName := context.Context.User
  69. clusterName := context.Context.Cluster
  70. _, userFound := userMap[userName]
  71. cluster, clusterFound := clusterMap[clusterName]
  72. // make sure the cluster is "allowed"
  73. _, aClusterFound := aClusterMap[clusterName]
  74. if userFound && clusterFound && aClusterFound {
  75. clusters = append(clusters, models.ClusterConfig{
  76. Name: clusterName,
  77. Server: cluster.Cluster.Server,
  78. Context: contextName,
  79. User: userName,
  80. })
  81. }
  82. }
  83. return clusters
  84. }
  85. // ToAllClusterConfigs converts a KubeConfig to a set of ClusterConfigs by
  86. // joining users and clusters on the context.
  87. func (k *KubeConfig) ToAllClusterConfigs() []models.ClusterConfig {
  88. clusters := make([]models.ClusterConfig, 0)
  89. // convert clusters, contexts, and users to maps for fast lookup
  90. clusterMap := k.createClusterMap()
  91. contextMap := k.createContextMap()
  92. userMap := k.createUserMap()
  93. // iterate through context maps and link to a user-cluster pair
  94. for contextName, context := range contextMap {
  95. userName := context.Context.User
  96. clusterName := context.Context.Cluster
  97. _, userFound := userMap[userName]
  98. cluster, clusterFound := clusterMap[clusterName]
  99. if userFound && clusterFound {
  100. clusters = append(clusters, models.ClusterConfig{
  101. Name: clusterName,
  102. Server: cluster.Cluster.Server,
  103. Context: contextName,
  104. User: userName,
  105. })
  106. }
  107. }
  108. return clusters
  109. }
  110. // createAllowedClusterMap creates a map from a cluster name to a KubeConfigCluster object
  111. func createAllowedClusterMap(clusters []string) map[string]string {
  112. aClusterMap := make(map[string]string)
  113. for _, cluster := range clusters {
  114. aClusterMap[cluster] = cluster
  115. }
  116. return aClusterMap
  117. }
  118. // createClusterMap creates a map from a cluster name to a KubeConfigCluster object
  119. func (k *KubeConfig) createClusterMap() map[string]KubeConfigCluster {
  120. clusterMap := make(map[string]KubeConfigCluster)
  121. for _, cluster := range k.Clusters {
  122. clusterMap[cluster.Name] = cluster
  123. }
  124. return clusterMap
  125. }
  126. // createContextMap creates a map from a context name to a KubeConfigContext object
  127. func (k *KubeConfig) createContextMap() map[string]KubeConfigContext {
  128. contextMap := make(map[string]KubeConfigContext)
  129. for _, context := range k.Contexts {
  130. contextMap[context.Name] = context
  131. }
  132. return contextMap
  133. }
  134. // createUserMap creates a map from a user name to a KubeConfigUser object
  135. func (k *KubeConfig) createUserMap() map[string]KubeConfigUser {
  136. userMap := make(map[string]KubeConfigUser)
  137. for _, user := range k.Users {
  138. userMap[user.Name] = user
  139. }
  140. return userMap
  141. }