utils.go 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. package main
  2. import (
  3. "fmt"
  4. "strings"
  5. "unicode"
  6. "devel.mephi.ru/dyokunev/go-sdapi/sdApi1"
  7. "devel.mephi.ru/dyokunev/go-sdapi/sdApi11"
  8. "github.com/alyu/configparser"
  9. "github.com/gophercloud/gophercloud"
  10. "github.com/gophercloud/gophercloud/openstack"
  11. "github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
  12. asuModels "devel.mephi.ru/dyokunev/go-asu-models"
  13. api11Models "devel.mephi.ru/dyokunev/go-sd-models/api11"
  14. )
  15. // H E L P E R S
  16. func checkErr(err error) {
  17. if err != nil {
  18. panic(err)
  19. }
  20. }
  21. func pointerFromBool(b bool) *bool {
  22. return &b
  23. }
  24. func capitalize(str string) string {
  25. runes := []rune(str)
  26. runes[0] = unicode.ToUpper(runes[0])
  27. return string(runes)
  28. }
  29. // O P E N S T A C K C L I E N T
  30. type OpenstackIdentityClient struct {
  31. client *gophercloud.ServiceClient
  32. config *configparser.Configuration
  33. domainID string
  34. }
  35. func initIdentityClient() OpenstackIdentityClient {
  36. config, err := configparser.Read("./project_and_roles.conf")
  37. checkErr(err)
  38. section, err := config.Section("openstack")
  39. checkErr(err)
  40. domainID := section.ValueOf("projects_domain_id")
  41. opts := gophercloud.AuthOptions{
  42. IdentityEndpoint: section.ValueOf("identity_endpoint"),
  43. DomainName: section.ValueOf("domain_name"),
  44. TenantName: section.ValueOf("project_name"),
  45. Username: section.ValueOf("username"),
  46. Password: section.ValueOf("password"),
  47. }
  48. provider, err := openstack.AuthenticatedClient(opts)
  49. checkErr(err)
  50. client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{
  51. Region: "Moscow",
  52. })
  53. checkErr(err)
  54. osclient := OpenstackIdentityClient{
  55. client: client,
  56. config: config,
  57. domainID: domainID,
  58. }
  59. return osclient
  60. }
  61. func projectsToMap(allProjects []projects.Project) map[int]projects.Project {
  62. projectsMap := map[int]projects.Project{}
  63. for _, project := range allProjects {
  64. if project.Extra["PersNumber"] == nil {
  65. panic(fmt.Sprintf("Project %s has no persNumber", project.Name))
  66. }
  67. persNumber := int(project.Extra["PersNumber"].(float64))
  68. projectsMap[persNumber] = project
  69. }
  70. return projectsMap
  71. }
  72. func (osclient OpenstackIdentityClient) getProjectsMap() map[int]projects.Project {
  73. listOpts := projects.ListOpts{
  74. DomainID: osclient.domainID,
  75. Enabled: pointerFromBool(true),
  76. IsDomain: pointerFromBool(false),
  77. }
  78. allPages, err := projects.List(osclient.client, listOpts).AllPages()
  79. checkErr(err)
  80. allProjects, err := projects.ExtractProjects(allPages)
  81. checkErr(err)
  82. return projectsToMap(allProjects)
  83. }
  84. func makeUpdateOpts(unit asuModels.Unit, domainID string) projects.UpdateOpts {
  85. updateOpts := projects.UpdateOpts{
  86. DomainID: domainID,
  87. Enabled: pointerFromBool(true),
  88. IsDomain: pointerFromBool(false),
  89. Name: fmt.Sprintf("%s [%v]", *unit.BriefName, *unit.PersNumber),
  90. Description: *unit.Name,
  91. Extra: map[string]interface{}{
  92. "ParentPersNumber": unit.ParentId},
  93. }
  94. return updateOpts
  95. }
  96. func makeCreateOpts(unit asuModels.Unit, domainID string) projects.CreateOpts {
  97. createOpts := projects.CreateOpts{
  98. DomainID: domainID,
  99. Enabled: pointerFromBool(true),
  100. IsDomain: pointerFromBool(false),
  101. Name: fmt.Sprintf("%s [%v]", *unit.BriefName, *unit.PersNumber),
  102. Description: *unit.Name,
  103. Extra: map[string]interface{}{
  104. "PersNumber": unit.PersNumber,
  105. "ParentPersNumber": unit.ParentId},
  106. }
  107. return createOpts
  108. }
  109. // U N I T S
  110. func getAllUnits(config *configparser.Configuration) asuModels.Units {
  111. section, err := config.Section("sd.mephi.ru")
  112. checkErr(err)
  113. sdApi1.SetApiKey(section.ValueOf("api1_key"))
  114. allUnits, err := sdApi1.GetUnits()
  115. checkErr(err)
  116. return allUnits
  117. }
  118. // Map of persNumber to Unit
  119. func getCleanUnitsMap(config *configparser.Configuration) map[int]asuModels.Unit {
  120. allUnits := getAllUnits(config)
  121. idToPersNum := map[int]int{}
  122. cleanUnits := map[int]asuModels.Unit{}
  123. // Get all not nil units without duplicates
  124. for _, unit := range allUnits {
  125. if unit.PersNumber == nil || unit.IsHidden == 1 || unit.Name == nil || unit.BriefName == nil {
  126. continue
  127. }
  128. idToPersNum[unit.Id] = *unit.PersNumber
  129. existingUnit, ok := cleanUnits[*unit.PersNumber]
  130. if !ok {
  131. cleanUnits[*unit.PersNumber] = unit
  132. } else {
  133. cleanUnits[*unit.PersNumber] = newestUnit(existingUnit, unit)
  134. }
  135. }
  136. for persNumber, unit := range cleanUnits {
  137. // Change parent ID to parent persNumber
  138. if unit.ParentId != nil {
  139. parentPersNumber := idToPersNum[*unit.ParentId]
  140. unit.ParentId = &parentPersNumber
  141. }
  142. // Clean names
  143. *unit.Name = strings.Join(strings.Fields(*unit.Name), " ")
  144. *unit.Name = capitalize(*unit.Name)
  145. *unit.BriefName = strings.Join(strings.Fields(*unit.BriefName), " ")
  146. *unit.BriefName = strings.ToUpper(*unit.BriefName)
  147. cleanUnits[persNumber] = unit
  148. }
  149. return cleanUnits
  150. }
  151. func newestUnit(unit1 asuModels.Unit, unit2 asuModels.Unit) asuModels.Unit {
  152. if unit1.CreateOrderDate != nil && unit2.CreateOrderDate != nil {
  153. if unit1.CreateOrderDate.Unix() > unit2.CreateOrderDate.Unix() {
  154. return unit1
  155. }
  156. return unit2
  157. }
  158. return unit1
  159. }
  160. // P E O P L E
  161. func getPeople(config *configparser.Configuration) api11Models.People {
  162. section, err := config.Section("sd.mephi.ru")
  163. checkErr(err)
  164. sdApi11.SetApiKey(section.ValueOf("api11_key"))
  165. people, err := sdApi11.GetPeople()
  166. checkErr(err)
  167. return people
  168. }