utils.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313
  1. package main
  2. import (
  3. "fmt"
  4. "strconv"
  5. "strings"
  6. "unicode"
  7. "devel.mephi.ru/dyokunev/go-sdapi/sdApi1"
  8. "devel.mephi.ru/dyokunev/go-sdapi/sdApi11"
  9. "devel.mephi.ru/dyokunev/go-sdapi/sdApi12"
  10. "github.com/alyu/configparser"
  11. "github.com/gophercloud/gophercloud"
  12. "github.com/gophercloud/gophercloud/openstack"
  13. "github.com/gophercloud/gophercloud/openstack/identity/v3/projects"
  14. "github.com/gophercloud/gophercloud/openstack/identity/v3/users"
  15. asuModels "devel.mephi.ru/dyokunev/go-asu-models"
  16. api11Models "devel.mephi.ru/dyokunev/go-sd-models/api11"
  17. api12Models "devel.mephi.ru/dyokunev/go-sd-models/api12"
  18. )
  19. // H E L P E R S
  20. func checkErr(err error) {
  21. if err != nil {
  22. panic(err)
  23. }
  24. }
  25. func pointerFromBool(b bool) *bool {
  26. return &b
  27. }
  28. func capitalize(str string) string {
  29. runes := []rune(str)
  30. runes[0] = unicode.ToUpper(runes[0])
  31. return string(runes)
  32. }
  33. // O P E N S T A C K C L I E N T
  34. type OpenstackIdentityClient struct {
  35. client *gophercloud.ServiceClient
  36. config *configparser.Configuration
  37. domainID string
  38. userRoleID string
  39. adminRoleID string
  40. }
  41. func initIdentityClient() OpenstackIdentityClient {
  42. config, err := configparser.Read("./project_and_roles.conf")
  43. checkErr(err)
  44. section, err := config.Section("openstack")
  45. checkErr(err)
  46. domainID := section.ValueOf("projects_domain_id")
  47. userRoleID := section.ValueOf("user_role_id")
  48. adminRoleID := section.ValueOf("admin_role_id")
  49. opts := gophercloud.AuthOptions{
  50. IdentityEndpoint: section.ValueOf("identity_endpoint"),
  51. DomainName: section.ValueOf("domain_name"),
  52. TenantName: section.ValueOf("project_name"),
  53. Username: section.ValueOf("username"),
  54. Password: section.ValueOf("password"),
  55. }
  56. provider, err := openstack.AuthenticatedClient(opts)
  57. checkErr(err)
  58. client, err := openstack.NewIdentityV3(provider, gophercloud.EndpointOpts{
  59. Region: section.ValueOf("region"),
  60. })
  61. checkErr(err)
  62. osclient := OpenstackIdentityClient{
  63. client: client,
  64. config: config,
  65. domainID: domainID,
  66. userRoleID: userRoleID,
  67. adminRoleID: adminRoleID,
  68. }
  69. return osclient
  70. }
  71. func (osclient OpenstackIdentityClient) getProjects() []projects.Project {
  72. listOpts := projects.ListOpts{
  73. DomainID: osclient.domainID,
  74. Enabled: pointerFromBool(true),
  75. IsDomain: pointerFromBool(false),
  76. }
  77. allPages, err := projects.List(osclient.client, listOpts).AllPages()
  78. checkErr(err)
  79. allProjects, err := projects.ExtractProjects(allPages)
  80. checkErr(err)
  81. return allProjects
  82. }
  83. func (osclient OpenstackIdentityClient) getProjectsMap() map[int]projects.Project {
  84. allProjects := osclient.getProjects()
  85. return projectsToMap(allProjects)
  86. }
  87. func projectsToMap(allProjects []projects.Project) map[int]projects.Project {
  88. projectsMap := map[int]projects.Project{}
  89. for _, project := range allProjects {
  90. if project.Extra["PersNumber"] == nil {
  91. panic(fmt.Sprintf("Project %s has no persNumber", project.Name))
  92. }
  93. persNumber := int(project.Extra["PersNumber"].(float64))
  94. projectsMap[persNumber] = project
  95. }
  96. return projectsMap
  97. }
  98. func (osclient OpenstackIdentityClient) getOpenstackUsers() []users.User {
  99. listOpts := users.ListOpts{
  100. DomainID: osclient.domainID,
  101. Enabled: pointerFromBool(true),
  102. }
  103. allPages, err := users.List(osclient.client, listOpts).AllPages()
  104. checkErr(err)
  105. allUsers, err := users.ExtractUsers(allPages)
  106. checkErr(err)
  107. return allUsers
  108. }
  109. func (osclient OpenstackIdentityClient) getOpenstackUsersMap() map[string]users.User {
  110. allUsers := osclient.getOpenstackUsers()
  111. return openstackUsersToMap(allUsers)
  112. }
  113. func openstackUsersToMap(allUsers []users.User) map[string]users.User {
  114. openstackUsersMap := map[string]users.User{}
  115. for _, user := range allUsers {
  116. openstackUsersMap[user.Name] = user
  117. }
  118. return openstackUsersMap
  119. }
  120. func makeUpdateOpts(unit asuModels.Unit, domainID string) projects.UpdateOpts {
  121. updateOpts := projects.UpdateOpts{
  122. DomainID: domainID,
  123. Enabled: pointerFromBool(true),
  124. IsDomain: pointerFromBool(false),
  125. Name: fmt.Sprintf("%s [%v]", *unit.BriefName, *unit.PersNumber),
  126. Description: *unit.Name,
  127. Extra: map[string]interface{}{
  128. "ParentPersNumber": unit.ParentId},
  129. }
  130. return updateOpts
  131. }
  132. func makeCreateOpts(unit asuModels.Unit, domainID string) projects.CreateOpts {
  133. createOpts := projects.CreateOpts{
  134. DomainID: domainID,
  135. Enabled: pointerFromBool(true),
  136. IsDomain: pointerFromBool(false),
  137. Name: fmt.Sprintf("%s [%v]", *unit.BriefName, *unit.PersNumber),
  138. Description: *unit.Name,
  139. Extra: map[string]interface{}{
  140. "PersNumber": unit.PersNumber,
  141. "ParentPersNumber": unit.ParentId},
  142. }
  143. return createOpts
  144. }
  145. // U N I T S
  146. func getAllUnits(config *configparser.Configuration) asuModels.Units {
  147. section, err := config.Section("sd.mephi.ru")
  148. checkErr(err)
  149. sdApi1.SetApiKey(section.ValueOf("api1_key"))
  150. allUnits, err := sdApi1.GetUnits()
  151. checkErr(err)
  152. return allUnits
  153. }
  154. func getCleanUnitsPersNumberMap(config *configparser.Configuration) map[int]asuModels.Unit {
  155. allUnits := getAllUnits(config)
  156. idToPersNum := map[int]int{}
  157. cleanUnits := map[int]asuModels.Unit{}
  158. // Get all not nil units without duplicates
  159. for _, unit := range allUnits {
  160. if unit.PersNumber == nil || unit.IsHidden == 1 || unit.Name == nil || unit.BriefName == nil {
  161. continue
  162. }
  163. idToPersNum[unit.Id] = *unit.PersNumber
  164. existingUnit, ok := cleanUnits[*unit.PersNumber]
  165. if !ok {
  166. cleanUnits[*unit.PersNumber] = unit
  167. } else {
  168. cleanUnits[*unit.PersNumber] = newestUnit(existingUnit, unit)
  169. }
  170. }
  171. for persNumber, unit := range cleanUnits {
  172. // Change parent ID to parent persNumber
  173. if unit.ParentId != nil {
  174. parentPersNumber := idToPersNum[*unit.ParentId]
  175. unit.ParentId = &parentPersNumber
  176. }
  177. // Clean names
  178. *unit.Name = strings.Join(strings.Fields(*unit.Name), " ")
  179. *unit.Name = capitalize(*unit.Name)
  180. *unit.BriefName = strings.Join(strings.Fields(*unit.BriefName), " ")
  181. *unit.BriefName = strings.ToUpper(*unit.BriefName)
  182. cleanUnits[persNumber] = unit
  183. }
  184. return cleanUnits
  185. }
  186. func getCleanUnitsCodeMap(config *configparser.Configuration) map[int]asuModels.Unit {
  187. units := getCleanUnitsPersNumberMap(config)
  188. codeToUnitsMap := map[int]asuModels.Unit{}
  189. for _, unit := range units {
  190. codeToUnitsMap[unitCodeToInt(unit.Code)] = unit
  191. }
  192. return codeToUnitsMap
  193. }
  194. func unitCodeToInt(code string) int {
  195. var numCode int
  196. code = strings.Replace(code, " ", "", -1)
  197. numCode, err := strconv.Atoi(code)
  198. checkErr(err)
  199. return numCode
  200. }
  201. func newestUnit(unit1 asuModels.Unit, unit2 asuModels.Unit) asuModels.Unit {
  202. if unit1.CreateOrderDate != nil && unit2.CreateOrderDate != nil {
  203. if unit1.CreateOrderDate.Unix() > unit2.CreateOrderDate.Unix() {
  204. return unit1
  205. }
  206. return unit2
  207. }
  208. return unit1
  209. }
  210. // P E O P L E
  211. func getPeople(config *configparser.Configuration) api11Models.People {
  212. section, err := config.Section("sd.mephi.ru")
  213. checkErr(err)
  214. sdApi11.SetApiKey(section.ValueOf("api11_key"))
  215. people, err := sdApi11.GetPeople()
  216. checkErr(err)
  217. return people
  218. }
  219. func getPeopleMap(config *configparser.Configuration) map[int]api11Models.Person {
  220. people := getPeople(config)
  221. return peopleToMap(people)
  222. }
  223. func peopleToMap(people api11Models.People) map[int]api11Models.Person {
  224. peopleMap := map[int]api11Models.Person{}
  225. for _, person := range people {
  226. peopleMap[person.Id] = person
  227. }
  228. return peopleMap
  229. }
  230. // R O L E S
  231. func getRoles(config *configparser.Configuration) api12Models.Roles {
  232. section, err := config.Section("sd.mephi.ru")
  233. checkErr(err)
  234. sdApi12.SetApiKey(section.ValueOf("api12_key"))
  235. heads, err := sdApi12.GetRoles(api12Models.Role{ServiceName: "voip", RoleName: "head"})
  236. checkErr(err)
  237. openstack_users, err := sdApi12.GetRoles(api12Models.Role{ServiceName: "voip", RoleName: "openstack_user"})
  238. checkErr(err)
  239. openstack_admins, err := sdApi12.GetRoles(api12Models.Role{ServiceName: "voip", RoleName: "openstack_admin"})
  240. checkErr(err)
  241. roles := append(heads, openstack_users...)
  242. roles := append(roles, openstack_admins...)
  243. return roles
  244. }