sku.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206
  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 aws
  15. import (
  16. "fmt"
  17. "yunion.io/x/cloudmux/pkg/cloudprovider"
  18. "yunion.io/x/pkg/errors"
  19. )
  20. type Product struct {
  21. ProductFamily string `json:"productFamily"`
  22. Attributes Attributes `json:"attributes"`
  23. Sku string `json:"sku"`
  24. }
  25. type Attributes struct {
  26. Availabilityzone string `json:"availabilityzone"`
  27. Classicnetworkingsupport string `json:"classicnetworkingsupport"`
  28. GPUMemory string `json:"gpuMemory"`
  29. Instancesku string `json:"instancesku"`
  30. Marketoption string `json:"marketoption"`
  31. RegionCode string `json:"regionCode"`
  32. Vpcnetworkingsupport string `json:"vpcnetworkingsupport"`
  33. EnhancedNetworkingSupported string `json:"enhancedNetworkingSupported"`
  34. IntelTurboAvailable string `json:"intelTurboAvailable"`
  35. Memory string `json:"memory"`
  36. DedicatedEbsThroughput string `json:"dedicatedEbsThroughput"`
  37. Vcpu int `json:"vcpu"`
  38. Gpu int `json:"gpu"`
  39. Capacitystatus string `json:"capacitystatus"`
  40. LocationType string `json:"locationType"`
  41. Storage string `json:"storage"`
  42. InstanceFamily string `json:"instanceFamily"`
  43. OperatingSystem string `json:"operatingSystem"`
  44. IntelAvx2Available string `json:"intelAvx2Available"`
  45. PhysicalProcessor string `json:"physicalProcessor"`
  46. ClockSpeed string `json:"clockSpeed"`
  47. Ecu string `json:"ecu"`
  48. NetworkPerformance string `json:"networkPerformance"`
  49. Servicename string `json:"servicename"`
  50. InstanceType string `json:"instanceType"`
  51. Tenancy string `json:"tenancy"`
  52. Usagetype string `json:"usagetype"`
  53. NormalizationSizeFactor string `json:"normalizationSizeFactor"`
  54. IntelAvxAvailable string `json:"intelAvxAvailable"`
  55. ProcessorFeatures string `json:"processorFeatures"`
  56. Servicecode string `json:"servicecode"`
  57. LicenseModel string `json:"licenseModel"`
  58. CurrentGeneration string `json:"currentGeneration"`
  59. PreInstalledSw string `json:"preInstalledSw"`
  60. Location string `json:"location"`
  61. ProcessorArchitecture string `json:"processorArchitecture"`
  62. Operation string `json:"operation"`
  63. VolumeApiName string `json:"volumeApiName"`
  64. }
  65. type Terms struct {
  66. OnDemand map[string]Term `json:"OnDemand"`
  67. Reserved map[string]Term `json:"Reserved"`
  68. }
  69. type Term struct {
  70. PriceDimensions map[string]Dimension `json:"priceDimensions"`
  71. Sku string `json:"sku"`
  72. EffectiveDate string `json:"effectiveDate"`
  73. OfferTermCode string `json:"offerTermCode"`
  74. TermAttributes TermAttributes `json:"termAttributes"`
  75. }
  76. type Dimension struct {
  77. Unit string `json:"unit"`
  78. EndRange string `json:"endRange"`
  79. Description string `json:"description"`
  80. AppliesTo []string `json:"appliesTo"`
  81. RateCode string `json:"rateCode"`
  82. BeginRange string `json:"beginRange"`
  83. PricePerUnit PricePerUnit `json:"pricePerUnit"`
  84. }
  85. type TermAttributes struct {
  86. LeaseContractLength string `json:"LeaseContractLength"`
  87. OfferingClass string `json:"OfferingClass"`
  88. PurchaseOption string `json:"PurchaseOption"`
  89. }
  90. type PricePerUnit struct {
  91. Usd float64 `json:"USD"`
  92. CNY float64 `json:"CNY"`
  93. }
  94. type SInstanceType struct {
  95. Product Product `json:"product"`
  96. ServiceCode string `json:"serviceCode"`
  97. Terms Terms `json:"terms"`
  98. Version string `json:"version"`
  99. PublicationDate string `json:"publicationDate"`
  100. }
  101. type InstanceType struct {
  102. InstanceType string `xml:"instanceType"`
  103. MemoryInfo struct {
  104. SizeInMiB int `xml:"sizeInMiB"`
  105. } `xml:"memoryInfo"`
  106. }
  107. func (self *SRegion) GetInstanceType(name string) (*InstanceType, error) {
  108. params := map[string]string{
  109. "InstanceType.1": name,
  110. }
  111. ret := struct {
  112. InstanceTypeSet []InstanceType `xml:"instanceTypeSet>item"`
  113. NextToken string `xml:"nextToken"`
  114. }{}
  115. err := self.ec2Request("DescribeInstanceTypes", params, &ret)
  116. if err != nil {
  117. return nil, err
  118. }
  119. for i := range ret.InstanceTypeSet {
  120. if ret.InstanceTypeSet[i].InstanceType == name {
  121. return &ret.InstanceTypeSet[i], nil
  122. }
  123. }
  124. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "%s", name)
  125. }
  126. func (self *SRegion) GetInstanceTypes(instanceType string) ([]SInstanceType, error) {
  127. filters := map[string]string{
  128. "regionCode": self.RegionId,
  129. "operatingSystem": "Linux",
  130. "licenseModel": "No License required",
  131. "productFamily": "Compute Instance",
  132. "operation": "RunInstances",
  133. "preInstalledSw": "NA",
  134. "tenancy": "Shared",
  135. "capacitystatus": "Used",
  136. }
  137. if len(instanceType) > 0 {
  138. filters["instanceType"] = instanceType
  139. }
  140. params := []ProductFilter{}
  141. for k, v := range filters {
  142. params = append(params, ProductFilter{
  143. Type: "TERM_MATCH",
  144. Field: k,
  145. Value: v,
  146. })
  147. }
  148. ret := []SInstanceType{}
  149. var nextToken string
  150. for {
  151. parts, _nextToken, err := self.GetProducts("AmazonEC2", params, nextToken)
  152. if err != nil {
  153. return nil, err
  154. }
  155. ret = append(ret, parts...)
  156. if len(_nextToken) == 0 || len(parts) == 0 {
  157. break
  158. }
  159. nextToken = _nextToken
  160. }
  161. return ret, nil
  162. }
  163. type Sku struct {
  164. InstanceType string `xml:"instanceType"`
  165. }
  166. func (self *SRegion) DescribeInstanceTypes(arch string, nextToken string) ([]Sku, string, error) {
  167. params := map[string]string{}
  168. if len(nextToken) > 0 {
  169. params["NextToken"] = nextToken
  170. }
  171. idx := 1
  172. if len(arch) > 0 {
  173. params[fmt.Sprintf("Filter.%d.Name", idx)] = "processor-info.supported-architecture"
  174. params[fmt.Sprintf("Filter.%d.Value.1", idx)] = arch
  175. idx++
  176. }
  177. ret := struct {
  178. InstanceTypeSet []Sku `xml:"instanceTypeSet>item"`
  179. NextToken string `xml:"nextToken"`
  180. }{}
  181. err := self.ec2Request("DescribeInstanceTypes", params, &ret)
  182. if err != nil {
  183. return nil, "", err
  184. }
  185. return ret.InstanceTypeSet, ret.NextToken, nil
  186. }