utils.go 8.2 KB

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