waf_instances.go 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586
  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 models
  15. import (
  16. "context"
  17. "fmt"
  18. "yunion.io/x/cloudmux/pkg/cloudprovider"
  19. "yunion.io/x/jsonutils"
  20. "yunion.io/x/log"
  21. "yunion.io/x/pkg/errors"
  22. "yunion.io/x/pkg/util/compare"
  23. "yunion.io/x/sqlchemy"
  24. "yunion.io/x/onecloud/pkg/apis"
  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/lockman"
  28. "yunion.io/x/onecloud/pkg/cloudcommon/db/taskman"
  29. "yunion.io/x/onecloud/pkg/cloudcommon/notifyclient"
  30. "yunion.io/x/onecloud/pkg/cloudcommon/validators"
  31. "yunion.io/x/onecloud/pkg/compute/options"
  32. "yunion.io/x/onecloud/pkg/httperrors"
  33. "yunion.io/x/onecloud/pkg/mcclient"
  34. "yunion.io/x/onecloud/pkg/util/stringutils2"
  35. )
  36. type SWafInstanceManager struct {
  37. db.SEnabledStatusInfrasResourceBaseManager
  38. db.SExternalizedResourceBaseManager
  39. SManagedResourceBaseManager
  40. SCloudregionResourceBaseManager
  41. }
  42. var WafInstanceManager *SWafInstanceManager
  43. func init() {
  44. WafInstanceManager = &SWafInstanceManager{
  45. SEnabledStatusInfrasResourceBaseManager: db.NewEnabledStatusInfrasResourceBaseManager(
  46. SWafInstance{},
  47. "waf_instances_tbl",
  48. "waf_instance",
  49. "waf_instances",
  50. ),
  51. }
  52. WafInstanceManager.SetVirtualObject(WafInstanceManager)
  53. }
  54. type SWafInstance struct {
  55. db.SEnabledStatusInfrasResourceBase
  56. db.SExternalizedResourceBase
  57. SManagedResourceBase
  58. SCloudregionResourceBase
  59. Type cloudprovider.TWafType `width:"20" charset:"ascii" nullable:"false" list:"domain" create:"required"`
  60. DefaultAction *cloudprovider.DefaultAction `charset:"ascii" nullable:"true" list:"domain" create:"domain_optional"`
  61. Cname string `width:"256" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  62. // 前面是否有代理服务
  63. IsAccessProduct bool `nullable:"false" default:"false" list:"user" update:"user" create:"optional"`
  64. AccessHeaders []string `width:"512" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  65. // 源站地址
  66. SourceIps []string `width:"512" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  67. // 回源地址
  68. CcList []string `width:"512" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  69. HttpPorts []int `width:"64" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  70. HttpsPorts []int `width:"64" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  71. UpstreamScheme string `width:"32" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  72. UpstreamPort int `nullable:"true" list:"user" update:"admin"`
  73. CertId string `width:"36" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  74. CertName string `width:"128" charset:"utf8" nullable:"true" list:"user" update:"admin"`
  75. }
  76. func (manager *SWafInstanceManager) GetContextManagers() [][]db.IModelManager {
  77. return [][]db.IModelManager{
  78. {CloudregionManager},
  79. }
  80. }
  81. func (manager *SWafInstanceManager) ValidateCreateData(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, input api.WafInstanceCreateInput) (api.WafInstanceCreateInput, error) {
  82. _region, err := validators.ValidateModel(ctx, userCred, CloudregionManager, &input.CloudregionId)
  83. if err != nil {
  84. return input, err
  85. }
  86. region := _region.(*SCloudregion)
  87. _provider, err := validators.ValidateModel(ctx, userCred, CloudproviderManager, &input.CloudproviderId)
  88. if err != nil {
  89. return input, err
  90. }
  91. provider := _provider.(*SCloudprovider)
  92. if !provider.IsAvailable() {
  93. return input, httperrors.NewInputParameterError("cloudprovider %s not available", provider.Name)
  94. }
  95. for i := range input.CloudResources {
  96. switch input.CloudResources[i].Type {
  97. case LoadbalancerManager.Keyword():
  98. _lb, err := validators.ValidateModel(ctx, userCred, LoadbalancerManager, &input.CloudResources[i].Id)
  99. if err != nil {
  100. return input, err
  101. }
  102. lb := _lb.(*SLoadbalancer)
  103. if lb.ManagerId != provider.GetId() {
  104. return input, httperrors.NewConflictError("lb %s does not belong to account %s", lb.Name, provider.GetName())
  105. }
  106. case GuestManager.Keyword():
  107. _server, err := validators.ValidateModel(ctx, userCred, GuestManager, &input.CloudResources[i].Id)
  108. if err != nil {
  109. return input, err
  110. }
  111. server := _server.(*SGuest)
  112. host, _ := server.GetHost()
  113. if host.ManagerId != provider.GetId() {
  114. return input, httperrors.NewConflictError("server %s does not belong to account %s", server.Name, provider.GetName())
  115. }
  116. default:
  117. return input, httperrors.NewInputParameterError("invalid %d resource type %s", i, input.CloudResources[i].Type)
  118. }
  119. }
  120. input, err = region.GetDriver().ValidateCreateWafInstanceData(ctx, userCred, input)
  121. if err != nil {
  122. return input, err
  123. }
  124. input.SetEnabled()
  125. input.EnabledStatusInfrasResourceBaseCreateInput, err = manager.SEnabledStatusInfrasResourceBaseManager.ValidateCreateData(ctx, userCred, ownerId, query, input.EnabledStatusInfrasResourceBaseCreateInput)
  126. if err != nil {
  127. return input, err
  128. }
  129. return input, nil
  130. }
  131. func (self *SWafInstance) PostCreate(ctx context.Context, userCred mcclient.TokenCredential, ownerId mcclient.IIdentityProvider, query jsonutils.JSONObject, data jsonutils.JSONObject) {
  132. self.SEnabledStatusInfrasResourceBase.PostCreate(ctx, userCred, ownerId, query, data)
  133. self.StartCreateTask(ctx, userCred, data.(*jsonutils.JSONDict))
  134. }
  135. func (self *SWafInstance) StartCreateTask(ctx context.Context, userCred mcclient.TokenCredential, params *jsonutils.JSONDict) error {
  136. task, err := taskman.TaskManager.NewTask(ctx, "WafCreateTask", self, userCred, params, "", "", nil)
  137. if err != nil {
  138. return errors.Wrapf(err, "NewTask")
  139. }
  140. self.SetStatus(ctx, userCred, api.WAF_STATUS_CREATING, "")
  141. return task.ScheduleRun(nil)
  142. }
  143. func (manager *SWafInstanceManager) FetchCustomizeColumns(
  144. ctx context.Context,
  145. userCred mcclient.TokenCredential,
  146. query jsonutils.JSONObject,
  147. objs []interface{},
  148. fields stringutils2.SSortedStrings,
  149. isList bool,
  150. ) []api.WafInstanceDetails {
  151. rows := make([]api.WafInstanceDetails, len(objs))
  152. stdRows := manager.SEnabledStatusInfrasResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  153. managerRows := manager.SManagedResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  154. regionRows := manager.SCloudregionResourceBaseManager.FetchCustomizeColumns(ctx, userCred, query, objs, fields, isList)
  155. insIds := make([]string, len(objs))
  156. for i := range rows {
  157. rows[i] = api.WafInstanceDetails{
  158. EnabledStatusInfrasResourceBaseDetails: stdRows[i],
  159. ManagedResourceInfo: managerRows[i],
  160. CloudregionResourceInfo: regionRows[i],
  161. }
  162. ins := objs[i].(*SWafInstance)
  163. insIds[i] = ins.Id
  164. }
  165. type WafRule struct {
  166. api.SWafRule
  167. WafInstanceId string
  168. }
  169. rules := []WafRule{}
  170. q := WafRuleManager.Query().In("waf_instance_id", insIds)
  171. err := q.All(&rules)
  172. if err != nil {
  173. return rows
  174. }
  175. ruleMaps := map[string][]api.SWafRule{}
  176. for _, rule := range rules {
  177. _, ok := ruleMaps[rule.WafInstanceId]
  178. if !ok {
  179. ruleMaps[rule.WafInstanceId] = []api.SWafRule{}
  180. }
  181. ruleMaps[rule.WafInstanceId] = append(ruleMaps[rule.WafInstanceId], rule.SWafRule)
  182. }
  183. for i := range rows {
  184. rows[i].Rules, _ = ruleMaps[insIds[i]]
  185. }
  186. return rows
  187. }
  188. // 列出WAF实例
  189. func (manager *SWafInstanceManager) ListItemFilter(
  190. ctx context.Context,
  191. q *sqlchemy.SQuery,
  192. userCred mcclient.TokenCredential,
  193. query api.WafInstanceListInput,
  194. ) (*sqlchemy.SQuery, error) {
  195. var err error
  196. q, err = manager.SEnabledStatusInfrasResourceBaseManager.ListItemFilter(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
  197. if err != nil {
  198. return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemFilter")
  199. }
  200. q, err = manager.SExternalizedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ExternalizedResourceBaseListInput)
  201. if err != nil {
  202. return nil, errors.Wrap(err, "SExternalizedResourceBaseManager.ListItemFilter")
  203. }
  204. q, err = manager.SManagedResourceBaseManager.ListItemFilter(ctx, q, userCred, query.ManagedResourceListInput)
  205. if err != nil {
  206. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemFilter")
  207. }
  208. q, err = manager.SCloudregionResourceBaseManager.ListItemFilter(ctx, q, userCred, query.RegionalFilterListInput)
  209. if err != nil {
  210. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemFilter")
  211. }
  212. return q, nil
  213. }
  214. func (manager *SWafInstanceManager) QueryDistinctExtraField(q *sqlchemy.SQuery, field string) (*sqlchemy.SQuery, error) {
  215. var err error
  216. q, err = manager.SEnabledStatusInfrasResourceBaseManager.QueryDistinctExtraField(q, field)
  217. if err == nil {
  218. return q, nil
  219. }
  220. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraField(q, field)
  221. if err == nil {
  222. return q, nil
  223. }
  224. q, err = manager.SCloudregionResourceBaseManager.QueryDistinctExtraField(q, field)
  225. if err == nil {
  226. return q, nil
  227. }
  228. return q, httperrors.ErrNotFound
  229. }
  230. func (manager *SWafInstanceManager) QueryDistinctExtraFields(q *sqlchemy.SQuery, resource string, fields []string) (*sqlchemy.SQuery, error) {
  231. var err error
  232. q, err = manager.SManagedResourceBaseManager.QueryDistinctExtraFields(q, resource, fields)
  233. if err == nil {
  234. return q, nil
  235. }
  236. return q, httperrors.ErrNotFound
  237. }
  238. func (manager *SWafInstanceManager) OrderByExtraFields(
  239. ctx context.Context,
  240. q *sqlchemy.SQuery,
  241. userCred mcclient.TokenCredential,
  242. query api.WafInstanceListInput,
  243. ) (*sqlchemy.SQuery, error) {
  244. q, err := manager.SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.EnabledStatusInfrasResourceBaseListInput)
  245. if err != nil {
  246. return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.OrderByExtraFields")
  247. }
  248. q, err = manager.SManagedResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.ManagedResourceListInput)
  249. if err != nil {
  250. return nil, errors.Wrap(err, "SManagedResourceBaseManager.OrderByExtraFields")
  251. }
  252. q, err = manager.SCloudregionResourceBaseManager.OrderByExtraFields(ctx, q, userCred, query.RegionalFilterListInput)
  253. if err != nil {
  254. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.OrderByExtraFields")
  255. }
  256. return q, nil
  257. }
  258. func (manager *SWafInstanceManager) ListItemExportKeys(ctx context.Context,
  259. q *sqlchemy.SQuery,
  260. userCred mcclient.TokenCredential,
  261. keys stringutils2.SSortedStrings,
  262. ) (*sqlchemy.SQuery, error) {
  263. q, err := manager.SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  264. if err != nil {
  265. return nil, errors.Wrap(err, "SEnabledStatusInfrasResourceBaseManager.ListItemExportKeys")
  266. }
  267. if keys.ContainsAny(manager.SCloudregionResourceBaseManager.GetExportKeys()...) {
  268. q, err = manager.SCloudregionResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  269. if err != nil {
  270. return nil, errors.Wrap(err, "SCloudregionResourceBaseManager.ListItemExportKeys")
  271. }
  272. }
  273. if keys.ContainsAny(manager.SManagedResourceBaseManager.GetExportKeys()...) {
  274. q, err = manager.SManagedResourceBaseManager.ListItemExportKeys(ctx, q, userCred, keys)
  275. if err != nil {
  276. return nil, errors.Wrap(err, "SManagedResourceBaseManager.ListItemExportKeys")
  277. }
  278. }
  279. return q, nil
  280. }
  281. func (self *SCloudregion) GetWafInstances(managerId string) ([]SWafInstance, error) {
  282. q := WafInstanceManager.Query().Equals("cloudregion_id", self.Id)
  283. if len(managerId) > 0 {
  284. q = q.Equals("manager_id", managerId)
  285. }
  286. wafs := []SWafInstance{}
  287. err := db.FetchModelObjects(WafInstanceManager, q, &wafs)
  288. return wafs, err
  289. }
  290. func (self *SCloudregion) SyncWafInstances(
  291. ctx context.Context,
  292. userCred mcclient.TokenCredential,
  293. provider *SCloudprovider,
  294. exts []cloudprovider.ICloudWafInstance,
  295. xor bool,
  296. ) ([]SWafInstance, []cloudprovider.ICloudWafInstance, compare.SyncResult) {
  297. lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
  298. defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), fmt.Sprintf("%s-%s", self.Id, provider.Id))
  299. result := compare.SyncResult{}
  300. localWafs := []SWafInstance{}
  301. remoteWafs := []cloudprovider.ICloudWafInstance{}
  302. dbWafs, err := self.GetWafInstances(provider.Id)
  303. if err != nil {
  304. result.Error(err)
  305. return nil, nil, result
  306. }
  307. removed := make([]SWafInstance, 0)
  308. commondb := make([]SWafInstance, 0)
  309. commonext := make([]cloudprovider.ICloudWafInstance, 0)
  310. added := make([]cloudprovider.ICloudWafInstance, 0)
  311. if err := compare.CompareSets(dbWafs, exts, &removed, &commondb, &commonext, &added); err != nil {
  312. result.Error(err)
  313. return nil, nil, result
  314. }
  315. for i := 0; i < len(removed); i++ {
  316. err := removed[i].syncRemove(ctx, userCred)
  317. if err != nil {
  318. result.DeleteError(err)
  319. continue
  320. }
  321. result.Delete()
  322. }
  323. if !xor {
  324. for i := 0; i < len(commondb); i++ {
  325. err := commondb[i].SyncWithCloudWafInstance(ctx, userCred, commonext[i])
  326. if err != nil {
  327. result.UpdateError(err)
  328. continue
  329. }
  330. localWafs = append(localWafs, commondb[i])
  331. remoteWafs = append(remoteWafs, commonext[i])
  332. result.Update()
  333. }
  334. }
  335. for i := 0; i < len(added); i++ {
  336. newWaf, err := self.newFromCloudWafInstance(ctx, userCred, provider, added[i])
  337. if err != nil {
  338. result.AddError(err)
  339. continue
  340. }
  341. localWafs = append(localWafs, *newWaf)
  342. remoteWafs = append(remoteWafs, added[i])
  343. result.Add()
  344. }
  345. return localWafs, remoteWafs, result
  346. }
  347. func (self *SWafInstance) CustomizeDelete(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, data jsonutils.JSONObject) error {
  348. return self.StartDeleteTask(ctx, userCred)
  349. }
  350. func (self *SWafInstance) StartDeleteTask(ctx context.Context, userCred mcclient.TokenCredential) error {
  351. task, err := taskman.TaskManager.NewTask(ctx, "WafDeleteTask", self, userCred, nil, "", "", nil)
  352. if err != nil {
  353. return errors.Wrapf(err, "NewTask")
  354. }
  355. self.SetStatus(ctx, userCred, api.WAF_STATUS_DELETING, "")
  356. return task.ScheduleRun(nil)
  357. }
  358. func (self *SWafInstance) Delete(ctx context.Context, userCred mcclient.TokenCredential) error {
  359. return nil
  360. }
  361. func (self *SWafInstance) RealDelete(ctx context.Context, userCred mcclient.TokenCredential) error {
  362. rules, err := self.GetWafRules()
  363. if err != nil {
  364. return errors.Wrapf(err, "GetWafRules")
  365. }
  366. for i := range rules {
  367. err = rules[i].RealDelete(ctx, userCred)
  368. if err != nil {
  369. return errors.Wrapf(err, "Delete Rule %s", rules[i].Name)
  370. }
  371. }
  372. return self.SEnabledStatusInfrasResourceBase.Delete(ctx, userCred)
  373. }
  374. func (self *SWafInstance) syncRemove(ctx context.Context, userCred mcclient.TokenCredential) error {
  375. err := self.RealDelete(ctx, userCred)
  376. if err != nil {
  377. return err
  378. }
  379. notifyclient.EventNotify(ctx, userCred, notifyclient.SEventNotifyParam{
  380. Obj: self,
  381. Action: notifyclient.ActionSyncDelete,
  382. })
  383. return nil
  384. }
  385. func (self *SWafInstance) GetIRegion(ctx context.Context) (cloudprovider.ICloudRegion, error) {
  386. region, err := self.GetRegion()
  387. if err != nil {
  388. return nil, errors.Wrapf(err, "GetRegion")
  389. }
  390. provider, err := self.GetDriver(ctx)
  391. if err != nil {
  392. return nil, errors.Wrapf(err, "GetDriver")
  393. }
  394. return provider.GetIRegionById(region.ExternalId)
  395. }
  396. func (self *SWafInstance) GetICloudWafInstance(ctx context.Context) (cloudprovider.ICloudWafInstance, error) {
  397. if len(self.ExternalId) == 0 {
  398. return nil, errors.Wrapf(cloudprovider.ErrNotFound, "empty external id")
  399. }
  400. iRegion, err := self.GetIRegion(ctx)
  401. if err != nil {
  402. return nil, errors.Wrapf(err, "GetIRegion")
  403. }
  404. return iRegion.GetICloudWafInstanceById(self.ExternalId)
  405. }
  406. func (self *SWafInstance) SyncWithCloudWafInstance(ctx context.Context, userCred mcclient.TokenCredential, ext cloudprovider.ICloudWafInstance) error {
  407. diff, err := db.Update(self, func() error {
  408. self.ExternalId = ext.GetGlobalId()
  409. self.SetEnabled(ext.GetEnabled())
  410. self.DefaultAction = ext.GetDefaultAction()
  411. self.Status = ext.GetStatus()
  412. self.IsAccessProduct = ext.GetIsAccessProduct()
  413. self.Type = ext.GetWafType()
  414. self.HttpsPorts = ext.GetHttpsPorts()
  415. self.HttpPorts = ext.GetHttpPorts()
  416. self.Cname = ext.GetCname()
  417. self.SourceIps = ext.GetSourceIps()
  418. if ccList := ext.GetCcList(); len(ccList) > 0 {
  419. self.CcList = ccList
  420. }
  421. if certId := ext.GetCertId(); len(certId) > 0 {
  422. self.CertId = certId
  423. }
  424. if certName := ext.GetCertName(); len(certName) > 0 {
  425. self.CertName = certName
  426. }
  427. self.UpstreamScheme = ext.GetUpstreamScheme()
  428. self.UpstreamPort = ext.GetUpstreamPort()
  429. self.AccessHeaders = ext.GetAccessHeaders()
  430. return nil
  431. })
  432. if len(diff) > 0 {
  433. notifyclient.EventNotify(ctx, userCred, notifyclient.SEventNotifyParam{
  434. Obj: self,
  435. Action: notifyclient.ActionSyncUpdate,
  436. })
  437. }
  438. if account := self.GetCloudaccount(); account != nil {
  439. syncMetadata(ctx, userCred, self, ext, account.ReadOnly)
  440. }
  441. return err
  442. }
  443. func (self *SCloudregion) newFromCloudWafInstance(ctx context.Context, userCred mcclient.TokenCredential, provider *SCloudprovider, ext cloudprovider.ICloudWafInstance) (*SWafInstance, error) {
  444. waf := &SWafInstance{}
  445. waf.SetModelManager(WafInstanceManager, waf)
  446. waf.SetEnabled(ext.GetEnabled())
  447. waf.CloudregionId = self.Id
  448. waf.ManagerId = provider.Id
  449. waf.Status = ext.GetStatus()
  450. waf.DefaultAction = ext.GetDefaultAction()
  451. waf.Type = ext.GetWafType()
  452. waf.ExternalId = ext.GetGlobalId()
  453. waf.IsAccessProduct = ext.GetIsAccessProduct()
  454. waf.HttpsPorts = ext.GetHttpsPorts()
  455. waf.HttpPorts = ext.GetHttpPorts()
  456. waf.Cname = ext.GetCname()
  457. waf.UpstreamScheme = ext.GetUpstreamScheme()
  458. waf.UpstreamPort = ext.GetUpstreamPort()
  459. waf.SourceIps = ext.GetSourceIps()
  460. waf.CcList = ext.GetCcList()
  461. waf.CertId = ext.GetCertId()
  462. waf.CertName = ext.GetCertName()
  463. waf.AccessHeaders = ext.GetAccessHeaders()
  464. var err = func() error {
  465. lockman.LockRawObject(ctx, WafInstanceManager.Keyword(), "name")
  466. defer lockman.ReleaseRawObject(ctx, WafInstanceManager.Keyword(), "name")
  467. var err error
  468. waf.Name, err = db.GenerateName(ctx, WafInstanceManager, userCred, ext.GetName())
  469. if err != nil {
  470. return errors.Wrapf(err, "db.GenerateName")
  471. }
  472. return WafInstanceManager.TableSpec().Insert(ctx, waf)
  473. }()
  474. if err != nil {
  475. return nil, err
  476. }
  477. syncMetadata(ctx, userCred, waf, ext, false)
  478. notifyclient.EventNotify(ctx, userCred, notifyclient.SEventNotifyParam{
  479. Obj: waf,
  480. Action: notifyclient.ActionSyncCreate,
  481. })
  482. return waf, nil
  483. }
  484. // 获取WAF绑定的资源列表
  485. func (self *SWafInstance) GetDetailsCloudResources(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject) (cloudprovider.SCloudResources, error) {
  486. ret := cloudprovider.SCloudResources{}
  487. iWaf, err := self.GetICloudWafInstance(ctx)
  488. if err != nil {
  489. return ret, httperrors.NewGeneralError(errors.Wrapf(err, "GetICloudWafInstance"))
  490. }
  491. ret.Data, err = iWaf.GetCloudResources()
  492. if err != nil {
  493. return ret, errors.Wrapf(err, "GetCloudResources")
  494. }
  495. ret.Total = len(ret.Data)
  496. return ret, nil
  497. }
  498. // 同步WAF状态
  499. func (self *SWafInstance) PerformSyncstatus(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.WafSyncstatusInput) (jsonutils.JSONObject, error) {
  500. return nil, StartResourceSyncStatusTask(ctx, userCred, self, "WafSyncstatusTask", "")
  501. }
  502. func (self *SWafInstance) PerformRemoteUpdate(ctx context.Context, userCred mcclient.TokenCredential, query jsonutils.JSONObject, input api.MongoDBRemoteUpdateInput) (jsonutils.JSONObject, error) {
  503. err := self.StartRemoteUpdateTask(ctx, userCred, (input.ReplaceTags != nil && *input.ReplaceTags), "")
  504. if err != nil {
  505. return nil, errors.Wrap(err, "StartRemoteUpdateTask")
  506. }
  507. return nil, nil
  508. }
  509. func (self *SWafInstance) StartRemoteUpdateTask(ctx context.Context, userCred mcclient.TokenCredential, replaceTags bool, parentTaskId string) error {
  510. data := jsonutils.NewDict()
  511. data.Add(jsonutils.NewBool(replaceTags), "replace_tags")
  512. task, err := taskman.TaskManager.NewTask(ctx, "WafInstanceRemoteUpdateTask", self, userCred, data, parentTaskId, "", nil)
  513. if err != nil {
  514. return errors.Wrap(err, "NewTask")
  515. }
  516. self.SetStatus(ctx, userCred, apis.STATUS_UPDATE_TAGS, "StartRemoteUpdateTask")
  517. return task.ScheduleRun(nil)
  518. }
  519. func (self *SWafInstance) OnMetadataUpdated(ctx context.Context, userCred mcclient.TokenCredential) {
  520. if len(self.ExternalId) == 0 || options.Options.KeepTagLocalization {
  521. return
  522. }
  523. if account := self.GetCloudaccount(); account != nil && account.ReadOnly {
  524. return
  525. }
  526. err := self.StartRemoteUpdateTask(ctx, userCred, true, "")
  527. if err != nil {
  528. log.Errorf("StartRemoteUpdateTask fail: %s", err)
  529. }
  530. }