mod_cloudregions.go 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. // Copyright 2019 Yunion
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package compute
  15. import (
  16. "sort"
  17. "yunion.io/x/cloudmux/pkg/cloudprovider"
  18. "yunion.io/x/jsonutils"
  19. "yunion.io/x/pkg/errors"
  20. "yunion.io/x/onecloud/pkg/mcclient"
  21. "yunion.io/x/onecloud/pkg/mcclient/modulebase"
  22. "yunion.io/x/onecloud/pkg/mcclient/modules"
  23. )
  24. type SCloudregionManager struct {
  25. modulebase.ResourceManager
  26. }
  27. var (
  28. Cloudregions SCloudregionManager
  29. )
  30. type sNameCounter struct {
  31. Name string
  32. Count int
  33. cloudprovider.SGeographicInfo
  34. }
  35. type tNameCounters []sNameCounter
  36. func (cc tNameCounters) Len() int { return len(cc) }
  37. func (cc tNameCounters) Swap(i, j int) { cc[i], cc[j] = cc[j], cc[i] }
  38. func (cc tNameCounters) Less(i, j int) bool {
  39. if cc[i].Count != cc[j].Count {
  40. return cc[i].Count > cc[j].Count
  41. }
  42. return cc[i].Name < cc[j].Name
  43. }
  44. func (this *SCloudregionManager) getRegionAttributeList(session *mcclient.ClientSession, params jsonutils.JSONObject, attr string) (jsonutils.JSONObject, error) {
  45. paramsDict := params.(*jsonutils.JSONDict)
  46. if limit, err := paramsDict.Int("limit"); err != nil || limit == 0 {
  47. paramsDict.Set("limit", jsonutils.NewInt(2048))
  48. }
  49. paramsDict.Set("details", jsonutils.JSONFalse)
  50. listResult, err := this.List(session, params)
  51. if err != nil {
  52. return nil, err
  53. }
  54. cities := map[string]*sNameCounter{}
  55. for i := range listResult.Data {
  56. cityStr, _ := listResult.Data[i].GetString(attr)
  57. if len(cityStr) == 0 && attr == "city" {
  58. cityStr = "Other"
  59. }
  60. if len(cityStr) > 0 {
  61. _, ok := cities[cityStr]
  62. if !ok {
  63. cities[cityStr] = &sNameCounter{
  64. Name: cityStr,
  65. Count: 0,
  66. }
  67. if attr == "city" {
  68. listResult.Data[i].Unmarshal(&cities[cityStr].SGeographicInfo)
  69. }
  70. }
  71. cities[cityStr].Count += 1
  72. }
  73. }
  74. cityList := make([]sNameCounter, len(cities))
  75. i := 0
  76. for k, v := range cities {
  77. cityList[i] = sNameCounter{Name: k, Count: v.Count, SGeographicInfo: v.SGeographicInfo}
  78. i += 1
  79. }
  80. sort.Sort(tNameCounters(cityList))
  81. return jsonutils.Marshal(cityList), nil
  82. }
  83. func (this *SCloudregionManager) GetRegionCities(session *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  84. return this.getRegionAttributeList(session, params, "city")
  85. }
  86. func (this *SCloudregionManager) GetRegionProviders(session *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  87. return this.getRegionAttributeList(session, params, "provider")
  88. }
  89. func (this *SCloudregionManager) GetCityServers(session *mcclient.ClientSession, params jsonutils.JSONObject) (jsonutils.JSONObject, error) {
  90. objs, err := this.GetRegionCities(session, params)
  91. if err != nil {
  92. return nil, errors.Wrapf(err, "GetRegionCities")
  93. }
  94. cities := []sNameCounter{}
  95. err = objs.Unmarshal(&cities)
  96. if err != nil {
  97. return nil, errors.Wrapf(err, "objs.Unmarshal")
  98. }
  99. _params := params.(*jsonutils.JSONDict)
  100. _params.Set("limit", jsonutils.NewInt(1))
  101. _params.Set("details", jsonutils.NewBool(false))
  102. for i := range cities {
  103. _params.Set("city", jsonutils.NewString(cities[i].Name))
  104. resp, err := Servers.List(session, _params)
  105. if err != nil {
  106. return nil, errors.Wrapf(err, "Servers.List")
  107. }
  108. cities[i].Count = resp.Total
  109. }
  110. sort.Sort(tNameCounters(cities))
  111. return jsonutils.Marshal(cities), nil
  112. }
  113. func init() {
  114. Cloudregions = SCloudregionManager{
  115. modules.NewComputeManager("cloudregion", "cloudregions",
  116. []string{"ID", "Name", "Enabled", "Status", "Provider",
  117. "Latitude", "Longitude", "City", "Country_Code",
  118. "vpc_count", "zone_count", "guest_count", "guest_increment_count",
  119. "External_Id"},
  120. []string{}),
  121. }
  122. modules.RegisterCompute(&Cloudregions)
  123. }