qcloud.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600
  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 regiondrivers
  15. import (
  16. "context"
  17. "fmt"
  18. "time"
  19. "yunion.io/x/cloudmux/pkg/cloudprovider"
  20. "yunion.io/x/jsonutils"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/util/billing"
  23. "yunion.io/x/pkg/utils"
  24. "yunion.io/x/sqlchemy"
  25. api "yunion.io/x/onecloud/pkg/apis/compute"
  26. "yunion.io/x/onecloud/pkg/cloudcommon/db"
  27. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  28. "yunion.io/x/onecloud/pkg/cloudcommon/validators"
  29. "yunion.io/x/onecloud/pkg/compute/models"
  30. "yunion.io/x/onecloud/pkg/httperrors"
  31. "yunion.io/x/onecloud/pkg/mcclient"
  32. "yunion.io/x/onecloud/pkg/util/choices"
  33. "yunion.io/x/onecloud/pkg/util/seclib2"
  34. )
  35. type SQcloudRegionDriver struct {
  36. SManagedVirtualizationRegionDriver
  37. }
  38. func init() {
  39. driver := SQcloudRegionDriver{}
  40. models.RegisterRegionDriver(&driver)
  41. }
  42. func (self *SQcloudRegionDriver) GetProvider() string {
  43. return api.CLOUD_PROVIDER_QCLOUD
  44. }
  45. func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.LoadbalancerCreateInput) (*api.LoadbalancerCreateInput, error) {
  46. return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerData(ctx, userCred, ownerId, input)
  47. }
  48. func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential,
  49. ownerId mcclient.IIdentityProvider, input *api.LoadbalancerListenerCreateInput,
  50. lb *models.SLoadbalancer, lbbg *models.SLoadbalancerBackendGroup) (*api.LoadbalancerListenerCreateInput, error) {
  51. if len(lbbg.ExternalId) > 0 {
  52. return input, httperrors.NewResourceBusyError("loadbalancer backend group %s has aleady used by other listener", lbbg.Name)
  53. }
  54. return input, nil
  55. }
  56. func (self *SQcloudRegionDriver) RequestCreateLoadbalancerBackendGroup(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, task taskman.ITask) error {
  57. return task.ScheduleRun(nil)
  58. }
  59. func (self *SQcloudRegionDriver) RequestCreateLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
  60. taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
  61. provider := lblis.GetCloudprovider()
  62. if provider == nil {
  63. return nil, fmt.Errorf("failed to find provider for lblis %s", lblis.Name)
  64. }
  65. opts, err := lblis.GetLoadbalancerListenerParams()
  66. if err != nil {
  67. return nil, errors.Wrapf(err, "lblis.GetLoadbalancerListenerParams")
  68. }
  69. {
  70. if lblis.ListenerType == api.LB_LISTENER_TYPE_HTTPS && len(lblis.CertificateId) > 0 {
  71. cert, err := lblis.GetCertificate()
  72. if err != nil {
  73. return nil, errors.Wrapf(err, "GetCertificate")
  74. }
  75. opts.CertificateId = cert.ExternalId
  76. }
  77. }
  78. lbbg, err := lblis.GetLoadbalancerBackendGroup()
  79. if err != nil {
  80. return nil, errors.Wrapf(err, "GetLoadbalancerBackendGroup")
  81. }
  82. lb, err := lblis.GetLoadbalancer()
  83. if err != nil {
  84. return nil, errors.Wrapf(err, "GetLoadbalancer")
  85. }
  86. iLb, err := lb.GetILoadbalancer(ctx)
  87. if err != nil {
  88. return nil, errors.Wrapf(err, "GetILoadbalancer")
  89. }
  90. iLis, err := iLb.CreateILoadBalancerListener(ctx, opts)
  91. if err != nil {
  92. return nil, errors.Wrapf(err, "CreateILoadBalancerListener")
  93. }
  94. err = db.SetExternalId(lbbg, userCred, iLis.GetGlobalId())
  95. if err != nil {
  96. return nil, errors.Wrapf(err, "lbbg.SetExternalId")
  97. }
  98. err = db.SetExternalId(lblis, userCred, iLis.GetGlobalId())
  99. if err != nil {
  100. return nil, errors.Wrapf(err, "lblis.SetExternalId")
  101. }
  102. backends, err := lbbg.GetBackends()
  103. if err != nil {
  104. return nil, errors.Wrapf(err, "GetBackends")
  105. }
  106. if len(backends) == 0 {
  107. return nil, nil
  108. }
  109. iLbbg, err := lbbg.GetICloudLoadbalancerBackendGroup(ctx)
  110. if err != nil {
  111. return nil, errors.Wrapf(err, "GetICloudLoadbalancerBackendGroup")
  112. }
  113. for i := range backends {
  114. opts := &cloudprovider.SLoadbalancerBackend{
  115. Weight: backends[i].Weight,
  116. Port: backends[i].Port,
  117. ExternalId: backends[i].ExternalId,
  118. }
  119. _, err := iLbbg.AddBackendServer(opts)
  120. if err != nil {
  121. return nil, errors.Wrapf(err, "AddBackendServer")
  122. }
  123. }
  124. return nil, nil
  125. })
  126. return nil
  127. }
  128. func (self *SQcloudRegionDriver) RequestDeleteLoadbalancerListener(ctx context.Context, userCred mcclient.TokenCredential, lblis *models.SLoadbalancerListener, task taskman.ITask) error {
  129. taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
  130. err := func() error {
  131. if len(lblis.ExternalId) == 0 {
  132. return nil
  133. }
  134. lb, err := lblis.GetLoadbalancer()
  135. if err != nil {
  136. return errors.Wrapf(err, "GetLoadbalancer")
  137. }
  138. iLb, err := lb.GetILoadbalancer(ctx)
  139. if err != nil {
  140. return errors.Wrapf(err, "GetILoadbalancer")
  141. }
  142. iListener, err := iLb.GetILoadBalancerListenerById(lblis.ExternalId)
  143. if err != nil {
  144. if errors.Cause(err) == cloudprovider.ErrNotFound {
  145. return nil
  146. }
  147. return errors.Wrapf(err, "GetILoadBalancerListenerById(%s)", lblis.ExternalId)
  148. }
  149. return iListener.Delete(ctx)
  150. }()
  151. if err != nil {
  152. return nil, err
  153. }
  154. lbbg, err := lblis.GetLoadbalancerBackendGroup()
  155. if err != nil {
  156. return nil, errors.Wrapf(err, "GetLoadbalancerBackendGroup")
  157. }
  158. return nil, db.SetExternalId(lbbg, userCred, "")
  159. })
  160. return nil
  161. }
  162. func (self *SQcloudRegionDriver) GetLoadbalancerListenerRuleInputParams(lblis *models.SLoadbalancerListener, lbr *models.SLoadbalancerListenerRule) *cloudprovider.SLoadbalancerListenerRule {
  163. scheduler := ""
  164. switch lblis.Scheduler {
  165. case api.LB_SCHEDULER_WRR:
  166. scheduler = "WRR"
  167. case api.LB_SCHEDULER_WLC:
  168. scheduler = "LEAST_CONN"
  169. case api.LB_SCHEDULER_SCH:
  170. scheduler = "IP_HASH"
  171. default:
  172. scheduler = "WRR"
  173. }
  174. sessionTimeout := 0
  175. if lblis.StickySession == api.LB_BOOL_ON {
  176. sessionTimeout = lblis.StickySessionCookieTimeout
  177. }
  178. rule := &cloudprovider.SLoadbalancerListenerRule{
  179. Name: lbr.Name,
  180. Domain: lbr.Domain,
  181. Path: lbr.Path,
  182. Scheduler: scheduler,
  183. HealthCheck: lblis.HealthCheck,
  184. HealthCheckType: lblis.HealthCheckType,
  185. HealthCheckTimeout: lblis.HealthCheckTimeout,
  186. HealthCheckDomain: lblis.HealthCheckDomain,
  187. HealthCheckHttpCode: lblis.HealthCheckHttpCode,
  188. HealthCheckURI: lblis.HealthCheckURI,
  189. HealthCheckInterval: lblis.HealthCheckInterval,
  190. HealthCheckRise: lblis.HealthCheckRise,
  191. HealthCheckFail: lblis.HealthCheckFall,
  192. StickySessionCookieTimeout: sessionTimeout,
  193. }
  194. return rule
  195. }
  196. func (self *SQcloudRegionDriver) RequestCreateLoadbalancerListenerRule(ctx context.Context, userCred mcclient.TokenCredential, lbr *models.SLoadbalancerListenerRule, task taskman.ITask) error {
  197. taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
  198. return nil, cloudprovider.ErrNotImplemented
  199. })
  200. return nil
  201. }
  202. func (self *SQcloudRegionDriver) ValidateCreateVpcData(ctx context.Context, userCred mcclient.TokenCredential, input api.VpcCreateInput) (api.VpcCreateInput, error) {
  203. cidrV := validators.NewIPv4PrefixValidator("cidr_block")
  204. if err := cidrV.Validate(ctx, jsonutils.Marshal(input).(*jsonutils.JSONDict)); err != nil {
  205. return input, err
  206. }
  207. err := IsInPrivateIpRange(cidrV.Value.ToIPRange())
  208. if err != nil {
  209. return input, err
  210. }
  211. if cidrV.Value.MaskLen < 16 || cidrV.Value.MaskLen > 28 {
  212. return input, httperrors.NewInputParameterError("%s request the mask range should be between 16 and 28", self.GetProvider())
  213. }
  214. return input, nil
  215. }
  216. func (self *SQcloudRegionDriver) ValidateUpdateLoadbalancerListenerData(ctx context.Context, userCred mcclient.TokenCredential,
  217. lblis *models.SLoadbalancerListener, input *api.LoadbalancerListenerUpdateInput) (*api.LoadbalancerListenerUpdateInput, error) {
  218. return input, nil
  219. }
  220. func (self *SQcloudRegionDriver) ValidateUpdateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential, lbbg *models.SLoadbalancerBackendGroup, input *api.LoadbalancerBackendUpdateInput) (*api.LoadbalancerBackendUpdateInput, error) {
  221. return input, nil
  222. }
  223. func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.LoadbalancerListenerRuleCreateInput) (*api.LoadbalancerListenerRuleCreateInput, error) {
  224. if len(input.Path) == 0 {
  225. return nil, httperrors.NewInputParameterError("path can not be emtpy")
  226. }
  227. return input, nil
  228. }
  229. func (self *SQcloudRegionDriver) ValidateUpdateLoadbalancerListenerRuleData(ctx context.Context, userCred mcclient.TokenCredential, input *api.LoadbalancerListenerRuleUpdateInput) (*api.LoadbalancerListenerRuleUpdateInput, error) {
  230. return input, nil
  231. }
  232. func (self *SQcloudRegionDriver) ValidateCreateLoadbalancerBackendData(ctx context.Context, userCred mcclient.TokenCredential,
  233. lb *models.SLoadbalancer, lbbg *models.SLoadbalancerBackendGroup, input *api.LoadbalancerBackendCreateInput) (*api.LoadbalancerBackendCreateInput, error) {
  234. return self.SManagedVirtualizationRegionDriver.ValidateCreateLoadbalancerBackendData(ctx, userCred, lb, lbbg, input)
  235. }
  236. func (self *SQcloudRegionDriver) RequestSyncLoadbalancerBackend(ctx context.Context, userCred mcclient.TokenCredential, lbb *models.SLoadbalancerBackend, task taskman.ITask) error {
  237. taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
  238. return nil, cloudprovider.ErrNotImplemented
  239. })
  240. return nil
  241. }
  242. func (self *SQcloudRegionDriver) InitDBInstanceUser(ctx context.Context, instance *models.SDBInstance, task taskman.ITask, desc *cloudprovider.SManagedDBInstanceCreateConfig) error {
  243. user := "root"
  244. account := models.SDBInstanceAccount{}
  245. account.DBInstanceId = instance.Id
  246. account.Name = user
  247. account.Host = "%"
  248. if instance.Engine == api.DBINSTANCE_TYPE_MYSQL && instance.Category == api.QCLOUD_DBINSTANCE_CATEGORY_BASIC {
  249. account.Host = "localhost"
  250. }
  251. account.Status = api.DBINSTANCE_USER_AVAILABLE
  252. account.SetModelManager(models.DBInstanceAccountManager, &account)
  253. err := models.DBInstanceAccountManager.TableSpec().Insert(ctx, &account)
  254. if err != nil {
  255. return errors.Wrapf(err, "Insert")
  256. }
  257. return account.SetPassword(desc.Password)
  258. }
  259. func (self *SQcloudRegionDriver) IsSupportedDBInstance() bool {
  260. return true
  261. }
  262. func (self *SQcloudRegionDriver) IsSupportedDBInstanceAutoRenew() bool {
  263. return true
  264. }
  265. func (self *SQcloudRegionDriver) GetRdsSupportSecgroupCount() int {
  266. return 5
  267. }
  268. func (self *SQcloudRegionDriver) ValidateCreateDBInstanceData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input api.DBInstanceCreateInput, skus []models.SDBInstanceSku, network *models.SNetwork) (api.DBInstanceCreateInput, error) {
  269. if input.Engine == api.DBINSTANCE_TYPE_MYSQL && input.Category != api.QCLOUD_DBINSTANCE_CATEGORY_BASIC && len(input.SecgroupIds) == 0 {
  270. input.SecgroupIds = []string{api.SECGROUP_DEFAULT_ID}
  271. }
  272. return input, nil
  273. }
  274. func (self *SQcloudRegionDriver) IsSupportedBillingCycle(bc billing.SBillingCycle, resource string) bool {
  275. switch resource {
  276. case models.DBInstanceManager.KeywordPlural(), models.ElasticcacheManager.KeywordPlural():
  277. years := bc.GetYears()
  278. months := bc.GetMonths()
  279. if (years >= 1 && years <= 3) || (months >= 1 && months <= 12) {
  280. return true
  281. }
  282. }
  283. return false
  284. }
  285. func (self *SQcloudRegionDriver) ValidateCreateDBInstanceBackupData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, instance *models.SDBInstance, input api.DBInstanceBackupCreateInput) (api.DBInstanceBackupCreateInput, error) {
  286. switch instance.Engine {
  287. case api.DBINSTANCE_TYPE_MYSQL:
  288. if instance.Category == api.QCLOUD_DBINSTANCE_CATEGORY_BASIC {
  289. return input, httperrors.NewNotSupportedError("Qcloud Basic MySQL instance not support create backup")
  290. }
  291. }
  292. return input, nil
  293. }
  294. func (self *SQcloudRegionDriver) ValidateCreateDBInstanceAccountData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, instance *models.SDBInstance, input api.DBInstanceAccountCreateInput) (api.DBInstanceAccountCreateInput, error) {
  295. return input, nil
  296. }
  297. func (self *SQcloudRegionDriver) ValidateCreateDBInstanceDatabaseData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, instance *models.SDBInstance, input api.DBInstanceDatabaseCreateInput) (api.DBInstanceDatabaseCreateInput, error) {
  298. return input, httperrors.NewNotSupportedError("Not support create Qcloud databases")
  299. }
  300. func (self *SQcloudRegionDriver) ValidateDBInstanceAccountPrivilege(ctx context.Context, userCred mcclient.TokenCredential, instance *models.SDBInstance, account string, privilege string) error {
  301. switch privilege {
  302. case api.DATABASE_PRIVILEGE_RW:
  303. case api.DATABASE_PRIVILEGE_R:
  304. default:
  305. return httperrors.NewInputParameterError("Unknown privilege %s", privilege)
  306. }
  307. return nil
  308. }
  309. func (self *SQcloudRegionDriver) IsSupportedElasticcacheSecgroup() bool {
  310. return true
  311. }
  312. func (self *SQcloudRegionDriver) GetMaxElasticcacheSecurityGroupCount() int {
  313. return 10
  314. }
  315. func (self *SQcloudRegionDriver) ValidateCreateElasticcacheData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, input *api.ElasticcacheCreateInput) (*api.ElasticcacheCreateInput, error) {
  316. if len(input.NetworkType) == 0 {
  317. input.NetworkType = api.LB_NETWORK_TYPE_VPC
  318. }
  319. input.Engine = "redis"
  320. return self.SManagedVirtualizationRegionDriver.ValidateCreateElasticcacheData(ctx, userCred, ownerId, input)
  321. }
  322. func (self *SQcloudRegionDriver) IsSupportedElasticcache() bool {
  323. return true
  324. }
  325. func (self *SQcloudRegionDriver) ValidateCreateElasticcacheAccountData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, data *jsonutils.JSONDict) (*jsonutils.JSONDict, error) {
  326. elasticCacheV := validators.NewModelIdOrNameValidator("elasticcache", "elasticcache", ownerId)
  327. accountTypeV := validators.NewStringChoicesValidator("account_type", choices.NewChoices("normal")).Default("normal")
  328. accountPrivilegeV := validators.NewStringChoicesValidator("account_privilege", choices.NewChoices("read", "write"))
  329. keyV := map[string]validators.IValidator{
  330. "elasticcache": elasticCacheV,
  331. "account_type": accountTypeV,
  332. "account_privilege": accountPrivilegeV.Default("read"),
  333. }
  334. for _, v := range keyV {
  335. if err := v.Validate(ctx, data); err != nil {
  336. return nil, err
  337. }
  338. }
  339. ec := elasticCacheV.Model.(*models.SElasticcache)
  340. if ec.Engine == "redis" && ec.EngineVersion == "2.8" {
  341. return nil, httperrors.NewNotSupportedError("redis version 2.8 not support create account")
  342. }
  343. passwd, _ := data.GetString("password")
  344. err := seclib2.ValidatePassword(passwd)
  345. if err != nil {
  346. return nil, err
  347. }
  348. return self.SManagedVirtualizationRegionDriver.ValidateCreateElasticcacheAccountData(ctx, userCred, ownerId, data)
  349. }
  350. func (self *SQcloudRegionDriver) RequestCreateElasticcacheAccount(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheAccount, task taskman.ITask) error {
  351. taskman.LocalTaskRun(task, func() (jsonutils.JSONObject, error) {
  352. _ec, err := db.FetchById(models.ElasticcacheManager, ea.ElasticcacheId)
  353. if err != nil {
  354. return nil, errors.Wrap(nil, "qcloudRegionDriver.CreateElasticcacheAccount.GetElasticcache")
  355. }
  356. ec := _ec.(*models.SElasticcache)
  357. iregion, err := ec.GetIRegion(ctx)
  358. if err != nil {
  359. return nil, errors.Wrap(nil, "qcloudRegionDriver.CreateElasticcacheAccount.GetIRegion")
  360. }
  361. params, err := ea.GetCreateQcloudElasticcacheAccountParams()
  362. if err != nil {
  363. return nil, errors.Wrap(err, "qcloudRegionDriver.CreateElasticcacheAccount.GetCreateQcloudElasticcacheAccountParams")
  364. }
  365. iec, err := iregion.GetIElasticcacheById(ec.GetExternalId())
  366. if err != nil {
  367. return nil, errors.Wrap(err, "qcloudRegionDriver.CreateElasticcacheAccount.GetIElasticcacheById")
  368. }
  369. iea, err := iec.CreateAccount(params)
  370. if err != nil {
  371. return nil, errors.Wrap(err, "qcloudRegionDriver.CreateElasticcacheAccount.CreateAccount")
  372. }
  373. ea.SetModelManager(models.ElasticcacheAccountManager, ea)
  374. if err := db.SetExternalId(ea, userCred, iea.GetGlobalId()); err != nil {
  375. return nil, errors.Wrap(err, "qcloudRegionDriver.CreateElasticcacheAccount.SetExternalId")
  376. }
  377. err = cloudprovider.WaitStatusWithDelay(iea, api.ELASTIC_CACHE_ACCOUNT_STATUS_AVAILABLE, 3*time.Second, 3*time.Second, 180*time.Second)
  378. if err != nil {
  379. return nil, errors.Wrap(err, "qcloudRegionDriver.CreateElasticcacheAccount.WaitStatusWithDelay")
  380. }
  381. if err = ea.SyncWithCloudElasticcacheAccount(ctx, userCred, iea); err != nil {
  382. return nil, errors.Wrap(err, "qcloudRegionDriver.CreateElasticcacheAccount.SyncWithCloudElasticcache")
  383. }
  384. return nil, nil
  385. })
  386. return nil
  387. }
  388. func (self *SQcloudRegionDriver) RequestElasticcacheAccountResetPassword(ctx context.Context, userCred mcclient.TokenCredential, ea *models.SElasticcacheAccount, task taskman.ITask) error {
  389. iregion, err := ea.GetIRegion(ctx)
  390. if err != nil {
  391. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.GetIRegion")
  392. }
  393. _ec, err := db.FetchById(models.ElasticcacheManager, ea.ElasticcacheId)
  394. if err != nil {
  395. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.FetchById")
  396. }
  397. ec := _ec.(*models.SElasticcache)
  398. iec, err := iregion.GetIElasticcacheById(ec.GetExternalId())
  399. if errors.Cause(err) == cloudprovider.ErrNotFound {
  400. return nil
  401. } else if err != nil {
  402. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.GetIElasticcacheById")
  403. }
  404. iea, err := iec.GetICloudElasticcacheAccount(ea.GetExternalId())
  405. if err != nil {
  406. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.GetICloudElasticcacheAccount")
  407. }
  408. data := task.GetParams()
  409. if data == nil {
  410. return errors.Wrap(fmt.Errorf("data is nil"), "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.GetParams")
  411. }
  412. input, err := ea.GetUpdateQcloudElasticcacheAccountParams(*data)
  413. if err != nil {
  414. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.GetUpdateQcloudElasticcacheAccountParams")
  415. }
  416. if iec.GetEngine() == "redis" && iec.GetEngineVersion() == "2.8" {
  417. pwd := ""
  418. if input.Password != nil {
  419. pwd = *input.Password
  420. }
  421. noAuth := false
  422. if len(pwd) > 0 {
  423. noAuth = false
  424. } else if input.NoPasswordAccess != nil {
  425. noAuth = *input.NoPasswordAccess
  426. } else if ec.AuthMode == "off" {
  427. noAuth = true
  428. }
  429. err = iec.UpdateAuthMode(noAuth, pwd)
  430. } else {
  431. err = iea.UpdateAccount(input)
  432. if err != nil {
  433. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.UpdateAccount")
  434. }
  435. }
  436. if input.Password != nil {
  437. err = ea.SavePassword(*input.Password)
  438. if err != nil {
  439. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.SavePassword")
  440. }
  441. if iea.GetName() == "root" {
  442. _, err := db.UpdateWithLock(ctx, ec, func() error {
  443. ec.AuthMode = api.LB_BOOL_ON
  444. return nil
  445. })
  446. if err != nil {
  447. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.UpdateAuthMode")
  448. }
  449. }
  450. }
  451. err = cloudprovider.WaitStatusWithDelay(iea, api.ELASTIC_CACHE_ACCOUNT_STATUS_AVAILABLE, 10*time.Second, 5*time.Second, 60*time.Second)
  452. if err != nil {
  453. return errors.Wrap(err, "qcloudRegionDriver.RequestElasticcacheAccountResetPassword.WaitStatusWithDelay")
  454. }
  455. return ea.SyncWithCloudElasticcacheAccount(ctx, userCred, iea)
  456. }
  457. func (self *SQcloudRegionDriver) IsCertificateBelongToRegion() bool {
  458. return false
  459. }
  460. func (self *SQcloudRegionDriver) ValidateCreateCdnData(ctx context.Context, userCred mcclient.TokenCredential, input api.CDNDomainCreateInput) (api.CDNDomainCreateInput, error) {
  461. if !utils.IsInStringArray(input.ServiceType, []string{
  462. api.CDN_SERVICE_TYPE_WEB,
  463. api.CND_SERVICE_TYPE_DOWNLOAD,
  464. api.CND_SERVICE_TYPE_MEDIA,
  465. }) {
  466. return input, httperrors.NewNotSupportedError("service_type %s", input.ServiceType)
  467. }
  468. if !utils.IsInStringArray(input.Area, []string{
  469. api.CDN_DOMAIN_AREA_MAINLAND,
  470. api.CDN_DOMAIN_AREA_OVERSEAS,
  471. api.CDN_DOMAIN_AREA_GLOBAL,
  472. }) {
  473. return input, httperrors.NewNotSupportedError("area %s", input.Area)
  474. }
  475. if input.Origins == nil {
  476. return input, httperrors.NewMissingParameterError("origins")
  477. }
  478. for _, origin := range *input.Origins {
  479. if len(origin.Origin) == 0 {
  480. return input, httperrors.NewMissingParameterError("origins.origin")
  481. }
  482. if !utils.IsInStringArray(origin.Type, []string{
  483. api.CDN_DOMAIN_ORIGIN_TYPE_DOMAIN,
  484. api.CDN_DOMAIN_ORIGIN_TYPE_IP,
  485. api.CDN_DOMAIN_ORIGIN_TYPE_BUCKET,
  486. api.CDN_DOMAIN_ORIGIN_THIRED_PARTY,
  487. }) {
  488. return input, httperrors.NewInputParameterError("invalid origin type %s", origin.Type)
  489. }
  490. }
  491. return input, nil
  492. }
  493. func (self *SQcloudRegionDriver) ValidateCreateSecurityGroupInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupCreateInput) (*api.SSecgroupCreateInput, error) {
  494. for i := range input.Rules {
  495. rule := input.Rules[i]
  496. if rule.Priority == nil {
  497. return nil, httperrors.NewMissingParameterError("priority")
  498. }
  499. if *rule.Priority < 0 || *rule.Priority > 99 {
  500. return nil, httperrors.NewInputParameterError("invalid priority %d, range 0-99", *rule.Priority)
  501. }
  502. }
  503. return input, nil
  504. }
  505. func (self *SQcloudRegionDriver) ValidateUpdateSecurityGroupRuleInput(ctx context.Context, userCred mcclient.TokenCredential, input *api.SSecgroupRuleUpdateInput) (*api.SSecgroupRuleUpdateInput, error) {
  506. if input.Priority != nil && (*input.Priority < 0 || *input.Priority > 99) {
  507. return nil, httperrors.NewInputParameterError("invalid priority %d, range 0-99", *input.Priority)
  508. }
  509. return self.SManagedVirtualizationRegionDriver.ValidateUpdateSecurityGroupRuleInput(ctx, userCred, input)
  510. }
  511. func (self *SQcloudRegionDriver) GetSecurityGroupFilter(vpc *models.SVpc) (func(q *sqlchemy.SQuery) *sqlchemy.SQuery, error) {
  512. return func(q *sqlchemy.SQuery) *sqlchemy.SQuery {
  513. return q.Equals("cloudregion_id", vpc.CloudregionId).Equals("manager_id", vpc.ManagerId)
  514. }, nil
  515. }