config.go 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920
  1. package service
  2. import (
  3. "bufio"
  4. "bytes"
  5. "context"
  6. "database/sql"
  7. "path/filepath"
  8. "strconv"
  9. "strings"
  10. "go-common/app/admin/main/config/model"
  11. "go-common/app/admin/main/config/pkg/lint"
  12. "go-common/library/ecode"
  13. "go-common/library/log"
  14. "github.com/jinzhu/gorm"
  15. )
  16. func lintConfig(filename, content string) error {
  17. ext := strings.TrimLeft(filepath.Ext(filename), ".")
  18. err := lint.Lint(ext, bytes.NewBufferString(content))
  19. if err != nil && err != lint.ErrLintNotExists {
  20. return ecode.Error(ecode.RequestErr, err.Error())
  21. }
  22. return nil
  23. }
  24. // CreateConf create config.
  25. func (s *Service) CreateConf(conf *model.Config, treeID int64, env, zone string, skiplint bool) error {
  26. // lint config
  27. if !skiplint {
  28. if err := lintConfig(conf.Name, conf.Comment); err != nil {
  29. return err
  30. }
  31. }
  32. app, err := s.AppByTree(treeID, env, zone)
  33. if err != nil {
  34. return err
  35. }
  36. conf.AppID = app.ID
  37. if _, err := s.configIng(conf.Name, app.ID); err == nil { // judge config is configIng
  38. return ecode.TargetBlocked
  39. }
  40. return s.dao.DB.Create(conf).Error
  41. }
  42. // LintConfig lint config file
  43. func (s *Service) LintConfig(filename, content string) ([]lint.LineErr, error) {
  44. ext := strings.TrimLeft(filepath.Ext(filename), ".")
  45. err := lint.Lint(ext, bytes.NewBufferString(content))
  46. if err == nil || err == lint.ErrLintNotExists {
  47. return make([]lint.LineErr, 0), nil
  48. }
  49. lintErr, ok := err.(lint.Error)
  50. if !ok {
  51. return nil, lintErr
  52. }
  53. return []lint.LineErr(lintErr), nil
  54. }
  55. // UpdateConfValue update config state.
  56. func (s *Service) UpdateConfValue(conf *model.Config, skiplint bool) (err error) {
  57. // lint config
  58. if !skiplint {
  59. if err := lintConfig(conf.Name, conf.Comment); err != nil {
  60. return err
  61. }
  62. }
  63. var confDB *model.Config
  64. if confDB, err = s.Config(conf.ID); err != nil {
  65. return
  66. }
  67. if confDB.State == model.ConfigIng { //judge config is configIng.
  68. if conf.Mtime != confDB.Mtime {
  69. err = ecode.TargetBlocked
  70. return
  71. }
  72. conf.Mtime = 0
  73. err = s.dao.DB.Model(&model.Config{State: model.ConfigIng}).Updates(conf).Error
  74. return
  75. }
  76. if _, err = s.configIng(confDB.Name, confDB.AppID); err == nil {
  77. err = ecode.TargetBlocked
  78. return
  79. }
  80. if err == sql.ErrNoRows || err == ecode.NothingFound {
  81. conf.ID = 0
  82. conf.AppID = confDB.AppID
  83. conf.Name = confDB.Name
  84. if conf.From == 0 {
  85. conf.From = confDB.From
  86. }
  87. conf.Mtime = 0
  88. return s.dao.DB.Create(conf).Error
  89. }
  90. return
  91. }
  92. // UpdateConfState update config state.
  93. func (s *Service) UpdateConfState(ID int64) (err error) {
  94. err = s.dao.DB.Model(&model.Config{ID: ID}).Update("state", model.ConfigEnd).Error
  95. return
  96. }
  97. // ConfigsByIDs get Config by IDs.
  98. func (s *Service) ConfigsByIDs(ids []int64) (confs []*model.Config, err error) {
  99. if err = s.dao.DB.Select("id,app_id,name,`from`,state,mark,operator,ctime,mtime,is_delete").Where(ids).Find(&confs).Error; err != nil {
  100. log.Error("ConfigsByIDs(%v) error(%v)", ids, err)
  101. if err == sql.ErrNoRows {
  102. err = nil
  103. }
  104. }
  105. return
  106. }
  107. // ConfigsByAppName get configs by app name.
  108. func (s *Service) ConfigsByAppName(appName, env, zone string, treeID int64, state int8) (confs []*model.Config, err error) {
  109. var app *model.App
  110. if app, err = s.AppByTree(treeID, env, zone); err != nil {
  111. if err == ecode.NothingFound {
  112. err = s.CreateApp(appName, env, zone, treeID)
  113. return
  114. }
  115. }
  116. if state != 0 {
  117. err = s.dao.DB.Select("id,app_id,name,`from`,state,mark,operator,is_delete,ctime,mtime").Where("app_id = ? and state =?", app.ID, state).Order("id desc").Find(&confs).Error
  118. } else {
  119. err = s.dao.DB.Select("id,app_id,name,`from`,state,mark,operator,is_delete,ctime,mtime").Where("app_id = ? ", app.ID).Order("id desc").Find(&confs).Error
  120. }
  121. if err != nil {
  122. if err == sql.ErrNoRows {
  123. err = nil
  124. }
  125. }
  126. return
  127. }
  128. // ConfigsByAppID configs by app ID.
  129. func (s *Service) ConfigsByAppID(appID int64, state int8) (confs []*model.Config, err error) {
  130. if state != 0 {
  131. err = s.dao.DB.Select("id,app_id,name,`from`,state,mark,operator,is_delete,ctime,mtime").Where("app_id = ? and state =?", appID, state).Order("id desc").Find(&confs).Error
  132. } else {
  133. err = s.dao.DB.Select("id,app_id,name,`from`,state,mark,operator,is_delete,ctime,mtime").Where("app_id = ? ", appID).Order("id desc").Find(&confs).Error
  134. }
  135. if err != nil {
  136. if err == sql.ErrNoRows {
  137. err = nil
  138. }
  139. }
  140. return
  141. }
  142. //ConfigSearchApp configSearchApp.
  143. func (s *Service) ConfigSearchApp(ctx context.Context, appName, env, zone, like string, buildID, treeID int64) (searchs []*model.ConfigSearch, err error) {
  144. var (
  145. app *model.App
  146. builds []*model.Build
  147. tags []*model.Tag
  148. confs []*model.Config
  149. tagIDs []int64
  150. confIDs []int64
  151. )
  152. if app, err = s.AppByTree(treeID, env, zone); err != nil {
  153. return
  154. }
  155. if builds, err = s.BuildsByApp(app.ID); err != nil {
  156. return
  157. }
  158. if len(builds) == 0 {
  159. return
  160. }
  161. for _, build := range builds {
  162. tagIDs = append(tagIDs, build.TagID)
  163. }
  164. if err = s.dao.DB.Where("id in(?)", tagIDs).Find(&tags).Error; err != nil {
  165. log.Error("tagsByIDs(%v) error(%v)", tagIDs, err)
  166. if err == sql.ErrNoRows {
  167. err = nil
  168. }
  169. return
  170. }
  171. tmp := make(map[int64]struct{})
  172. for _, tag := range tags {
  173. tmpIDs := strings.Split(tag.ConfigIDs, ",")
  174. for _, tmpID := range tmpIDs {
  175. var id int64
  176. if id, err = strconv.ParseInt(tmpID, 10, 64); err != nil {
  177. log.Error("strconv.ParseInt() error(%v)", err)
  178. return
  179. }
  180. if _, ok := tmp[id]; !ok {
  181. tmp[id] = struct{}{}
  182. confIDs = append(confIDs, id)
  183. }
  184. }
  185. }
  186. if err = s.dao.DB.Where("id in (?) AND comment like(?) ", confIDs, "%"+like+"%").Find(&confs).Error; err != nil {
  187. log.Error("confsByIDs(%v) error(%v)", confIDs, err)
  188. if err == sql.ErrNoRows {
  189. err = nil
  190. }
  191. return
  192. }
  193. for _, conf := range confs {
  194. search := new(model.ConfigSearch)
  195. search.App = appName
  196. for _, tag := range tags {
  197. tmpIDs := strings.Split(tag.ConfigIDs, ",")
  198. for _, tmpID := range tmpIDs {
  199. var id int64
  200. if id, err = strconv.ParseInt(tmpID, 10, 64); err != nil {
  201. log.Error("strconv.ParseInt() error(%v)", err)
  202. return
  203. }
  204. if id != conf.ID { //judge config is in build.
  205. continue
  206. }
  207. for _, build := range builds {
  208. if build.ID == tag.BuildID {
  209. search.Builds = append(search.Builds, build.Name)
  210. }
  211. }
  212. }
  213. }
  214. //generate comment.
  215. search.ConfValues = genComments(conf.Comment, like)
  216. search.ConfID = conf.ID
  217. search.Mark = conf.Mark
  218. search.ConfName = conf.Name
  219. searchs = append(searchs, search)
  220. }
  221. return
  222. }
  223. //ConfigSearchAll configSearchAll.
  224. func (s *Service) ConfigSearchAll(ctx context.Context, env, zone, like string, nodes *model.CacheData) (searchs []*model.ConfigSearch, err error) {
  225. var (
  226. apps []*model.App
  227. builds []*model.Build
  228. tags []*model.Tag
  229. confs []*model.Config
  230. names []string
  231. appIDs []int64
  232. tagIDs []int64
  233. configIDs []int64
  234. )
  235. searchs = make([]*model.ConfigSearch, 0)
  236. if len(nodes.Data) == 0 {
  237. return
  238. }
  239. for _, node := range nodes.Data {
  240. names = append(names, node.Path)
  241. }
  242. if err = s.dao.DB.Where("env =? and zone =? and name in(?)", env, zone, names).Find(&apps).Error; err != nil {
  243. log.Error("AppList() find apps() error(%v)", err)
  244. if err == sql.ErrNoRows {
  245. err = nil
  246. }
  247. return
  248. }
  249. for _, app := range apps {
  250. appIDs = append(appIDs, app.ID)
  251. }
  252. if err = s.dao.DB.Where("app_id in(?) ", appIDs).Find(&builds).Error; err != nil {
  253. log.Error("BuildsByAppIDs(%v) error(%v)", appIDs, err)
  254. if err == sql.ErrNoRows {
  255. err = nil
  256. }
  257. return
  258. }
  259. for _, build := range builds {
  260. tagIDs = append(tagIDs, build.TagID)
  261. }
  262. if err = s.dao.DB.Where("id in(?)", tagIDs).Find(&tags).Error; err != nil {
  263. log.Error("tagsByIDs(%v) error(%v)", tagIDs, err)
  264. if err == sql.ErrNoRows {
  265. err = nil
  266. }
  267. return
  268. }
  269. tmp := make(map[int64]struct{})
  270. for _, tag := range tags {
  271. tmpIDs := strings.Split(tag.ConfigIDs, ",")
  272. for _, tmpID := range tmpIDs {
  273. var id int64
  274. if id, err = strconv.ParseInt(tmpID, 10, 64); err != nil {
  275. log.Error("strconv.ParseInt() error(%v)", err)
  276. return
  277. }
  278. if _, ok := tmp[id]; !ok {
  279. tmp[id] = struct{}{}
  280. configIDs = append(configIDs, id)
  281. }
  282. }
  283. }
  284. if err = s.dao.DB.Where("id in (?) and comment like(?) ", configIDs, "%"+like+"%").Find(&confs).Error; err != nil {
  285. log.Error("confsByIDs(%v) error(%v)", configIDs, err)
  286. if err == sql.ErrNoRows {
  287. err = nil
  288. }
  289. return
  290. }
  291. if len(confs) == 0 {
  292. return
  293. }
  294. // convert confs to confSearch.
  295. for _, conf := range confs {
  296. search := new(model.ConfigSearch)
  297. for _, app := range apps {
  298. if app.ID == conf.AppID {
  299. search.App = app.Name
  300. search.TreeID = app.TreeID
  301. }
  302. }
  303. for _, tag := range tags {
  304. tmpIDs := strings.Split(tag.ConfigIDs, ",")
  305. for _, tmpID := range tmpIDs {
  306. var id int64
  307. if id, err = strconv.ParseInt(tmpID, 10, 64); err != nil {
  308. log.Error("strconv.ParseInt() error(%v)", err)
  309. return
  310. }
  311. if id != conf.ID { //judge config is in build.
  312. continue
  313. }
  314. for _, build := range builds {
  315. if build.ID == tag.BuildID {
  316. search.Builds = append(search.Builds, build.Name)
  317. }
  318. }
  319. }
  320. }
  321. //generate comment.
  322. search.ConfValues = genComments(conf.Comment, like)
  323. search.ConfID = conf.ID
  324. search.Mark = conf.Mark
  325. search.ConfName = conf.Name
  326. searchs = append(searchs, search)
  327. }
  328. return
  329. }
  330. func genComments(comment, like string) (comments []string) {
  331. var (
  332. line []byte
  333. l, cur []byte
  334. err error
  335. )
  336. wbuf := new(bytes.Buffer)
  337. rbuf := bufio.NewReader(strings.NewReader(comment))
  338. for {
  339. l = line
  340. if line, _, err = rbuf.ReadLine(); err != nil {
  341. break
  342. }
  343. if bytes.Contains(line, []byte(like)) {
  344. cur = line
  345. wbuf.Write(l)
  346. wbuf.WriteString("\n")
  347. wbuf.Write(cur)
  348. wbuf.WriteString("\n")
  349. line, _, _ = rbuf.ReadLine()
  350. wbuf.Write(line)
  351. wbuf.WriteString("\n")
  352. comments = append(comments, wbuf.String())
  353. wbuf.Reset()
  354. }
  355. }
  356. return
  357. }
  358. //Configs configs.
  359. func (s *Service) Configs(appName, env, zone string, buildID, treeID int64) (res *model.ConfigRes, err error) {
  360. var (
  361. allConfs []*model.Config
  362. buildConfs []*model.Config
  363. lastConfs []*model.Config
  364. app *model.App
  365. build *model.Build
  366. )
  367. if app, err = s.AppByTree(treeID, env, zone); err != nil {
  368. if err == ecode.NothingFound {
  369. err = s.CreateApp(appName, env, zone, treeID)
  370. return
  371. }
  372. }
  373. if allConfs, err = s.ConfigsByAppID(app.ID, 0); err != nil {
  374. return
  375. }
  376. if buildID != 0 {
  377. if build, err = s.Build(buildID); err != nil {
  378. return
  379. }
  380. if build.AppID != app.ID {
  381. err = ecode.NothingFound
  382. return
  383. }
  384. tagID := build.TagID
  385. if tagID == 0 {
  386. return
  387. }
  388. if buildConfs, err = s.ConfigsByTagID(tagID); err != nil {
  389. return
  390. }
  391. if lastConfs, err = s.LastBuildConfigConfigs(build.AppID, buildID); err != nil {
  392. if err != ecode.NothingFound {
  393. return
  394. }
  395. err = nil
  396. }
  397. }
  398. tmpMap := make(map[string]struct{})
  399. res = new(model.ConfigRes)
  400. for _, conf := range allConfs {
  401. if _, ok := tmpMap[conf.Name]; ok {
  402. continue
  403. }
  404. //new common
  405. if conf.From > 0 {
  406. conf.NewCommon, _ = s.NewCommon(conf.From)
  407. }
  408. tmpMap[conf.Name] = struct{}{}
  409. var bool bool
  410. for _, bconf := range buildConfs {
  411. //new common
  412. if bconf.From > 0 {
  413. bconf.NewCommon, _ = s.NewCommon(bconf.From)
  414. }
  415. if bconf.Name == conf.Name {
  416. if bconf.ID != conf.ID {
  417. if conf.IsDelete != 1 {
  418. res.BuildNewFile = append(res.BuildNewFile, conf)
  419. }
  420. }
  421. bf := &model.BuildFile{Config: bconf}
  422. if bf.IsDelete == 0 {
  423. res.BuildFiles = append(res.BuildFiles, bf)
  424. }
  425. for _, lconf := range lastConfs {
  426. if lconf.Name == bconf.Name {
  427. if lconf.ID != bconf.ID {
  428. bf.LastConf = lconf
  429. }
  430. }
  431. }
  432. bool = true
  433. break
  434. }
  435. }
  436. if !bool {
  437. if conf.IsDelete != 1 {
  438. res.Files = append(res.Files, conf)
  439. }
  440. continue
  441. }
  442. }
  443. return
  444. }
  445. // NewCommon get new common id
  446. func (s *Service) NewCommon(from int64) (new int64, err error) {
  447. common := &model.CommonConf{}
  448. newCommon := &model.CommonConf{}
  449. if err = s.dao.DB.First(&common, from).Error; err != nil {
  450. log.Error("NewCommon.First.from(%d) error(%v)", from, err)
  451. return
  452. }
  453. if err = s.dao.DB.Where("team_id = ? and name = ? and state = 2", common.TeamID, common.Name).Order("id desc").First(&newCommon).Error; err != nil {
  454. log.Error("NewCommon.Order.First.common(%v) error(%v)", common, err)
  455. return
  456. }
  457. new = newCommon.ID
  458. return
  459. }
  460. //ConfigRefs configRefs.
  461. func (s *Service) ConfigRefs(appName, env, zone string, buildID, treeID int64) (res []*model.ConfigRefs, err error) {
  462. var (
  463. allConfs []*model.Config
  464. buildConfs []*model.Config
  465. num int
  466. ok bool
  467. ref *model.ConfigRefs
  468. )
  469. if allConfs, err = s.ConfigsByAppName(appName, env, zone, treeID, model.ConfigEnd); err != nil {
  470. return
  471. }
  472. if buildID != 0 {
  473. if buildConfs, err = s.ConfigsByBuildID(buildID); err != nil {
  474. return
  475. }
  476. }
  477. tmpMap := make(map[string]int)
  478. refs := make(map[string]*model.ConfigRefs)
  479. for _, conf := range allConfs {
  480. if num, ok = tmpMap[conf.Name]; !ok {
  481. ref = new(model.ConfigRefs)
  482. refs[conf.Name] = ref
  483. tmpMap[conf.Name] = num
  484. } else {
  485. ref = refs[conf.Name]
  486. }
  487. if num <= 5 {
  488. ref.Configs = append(ref.Configs, &model.ConfigRef{ID: conf.ID, Mark: conf.Mark})
  489. tmpMap[conf.Name] = num + 1
  490. }
  491. if ref.Ref != nil {
  492. continue
  493. }
  494. for _, bconf := range buildConfs {
  495. if bconf.Name == conf.Name {
  496. ref.Ref = &model.ConfigRef{ID: bconf.ID, Mark: bconf.Mark}
  497. break
  498. }
  499. }
  500. }
  501. for k, v := range refs {
  502. v.Name = k
  503. res = append(res, v)
  504. }
  505. return
  506. }
  507. // ConfigsByBuildID get configs by build ID.
  508. func (s *Service) ConfigsByBuildID(buildID int64) (confs []*model.Config, err error) {
  509. var (
  510. build *model.Build
  511. )
  512. if build, err = s.Build(buildID); err != nil {
  513. return
  514. }
  515. tagID := build.TagID
  516. if tagID == 0 {
  517. return
  518. }
  519. return s.ConfigsByTagID(tagID)
  520. }
  521. // LastBuildConfigs get configs by build ID.
  522. func (s *Service) LastBuildConfigs(appID, buildID int64) (confs []*model.Config, err error) {
  523. var (
  524. tag *model.Tag
  525. ids []int64
  526. id int64
  527. )
  528. if tag, err = s.LastTagByAppBuild(appID, buildID); err != nil {
  529. return
  530. }
  531. confIDs := tag.ConfigIDs
  532. if len(confIDs) == 0 {
  533. return
  534. }
  535. tmpIDs := strings.Split(confIDs, ",")
  536. for _, tmpID := range tmpIDs {
  537. if id, err = strconv.ParseInt(tmpID, 10, 64); err != nil {
  538. log.Error("strconv.ParseInt(%s) error(%v)", tmpID, err)
  539. return
  540. }
  541. ids = append(ids, id)
  542. }
  543. return s.ConfigsByIDs(ids)
  544. }
  545. // LastBuildConfigConfigs get configs by build ID.
  546. func (s *Service) LastBuildConfigConfigs(appID, buildID int64) (confs []*model.Config, err error) {
  547. var (
  548. tag *model.Tag
  549. ids []int64
  550. id int64
  551. tmps []*model.Config
  552. cids []int64
  553. lastIDS []int64
  554. )
  555. if tag, err = s.TagByAppBuild(appID, buildID); err != nil {
  556. return
  557. }
  558. confIDs := tag.ConfigIDs
  559. if len(confIDs) == 0 {
  560. return
  561. }
  562. tmpIDs := strings.Split(confIDs, ",")
  563. for _, tmpID := range tmpIDs {
  564. if id, err = strconv.ParseInt(tmpID, 10, 64); err != nil {
  565. log.Error("strconv.ParseInt(%s) error(%v)", tmpID, err)
  566. return
  567. }
  568. ids = append(ids, id)
  569. }
  570. tmps, err = s.ConfigsByIDs(ids)
  571. if err != nil {
  572. log.Error("LastBuildConfigConfigs ids(%v) error(%v)", ids, err)
  573. return
  574. }
  575. for _, val := range tmps {
  576. cs, err := s.ConfigList(val.AppID, val.Name)
  577. if err == nil {
  578. cids = nil
  579. csloop:
  580. for _, vv := range cs {
  581. for _, vvv := range ids {
  582. if vvv == vv.ID {
  583. continue csloop
  584. }
  585. }
  586. cids = append(cids, vv.ID)
  587. }
  588. if configID, err := s.TagByAppBuildLastConfig(appID, buildID, tag.ID, cids); err == nil {
  589. lastIDS = append(lastIDS, configID)
  590. }
  591. }
  592. }
  593. return s.ConfigsByIDs(lastIDS)
  594. }
  595. // ConfigList ...
  596. func (s *Service) ConfigList(appID int64, name string) (confs []*model.Config, err error) {
  597. if err = s.dao.DB.Where("app_id = ? and name = ?", appID, name).Order("id desc").Find(&confs).Error; err != nil {
  598. log.Error("ConfigList appid(%v) name(%v) error(%v)", appID, name, err)
  599. }
  600. return
  601. }
  602. // ConfigsByTagID get configs by tag id.
  603. func (s *Service) ConfigsByTagID(tagID int64) (confs []*model.Config, err error) {
  604. var (
  605. tag *model.Tag
  606. ids []int64
  607. id int64
  608. )
  609. if tag, err = s.Tag(tagID); err != nil {
  610. return
  611. }
  612. confIDs := tag.ConfigIDs
  613. if len(confIDs) == 0 {
  614. err = ecode.NothingFound
  615. return
  616. }
  617. tmpIDs := strings.Split(confIDs, ",")
  618. for _, tmpID := range tmpIDs {
  619. if id, err = strconv.ParseInt(tmpID, 10, 64); err != nil {
  620. log.Error("strconv.ParseInt(%s) error(%v)", tmpID, err)
  621. return
  622. }
  623. ids = append(ids, id)
  624. }
  625. return s.ConfigsByIDs(ids)
  626. }
  627. //Config get Config by Config ID.
  628. func (s *Service) Config(ID int64) (conf *model.Config, err error) {
  629. conf = new(model.Config)
  630. err = s.dao.DB.First(&conf, ID).Error
  631. return
  632. }
  633. func (s *Service) configIng(name string, appID int64) (conf *model.Config, err error) {
  634. conf = new(model.Config)
  635. if err = s.dao.DB.Select("id").Where("name = ? and app_id = ? and state=?", name, appID, model.ConfigIng).First(&conf).Error; err != nil {
  636. log.Error("configIng(%v) error(%v)", name, err)
  637. if err == sql.ErrNoRows {
  638. err = ecode.NothingFound
  639. }
  640. }
  641. return
  642. }
  643. //Value get value by Config ID.
  644. func (s *Service) Value(ID int64) (conf *model.Config, err error) {
  645. conf = new(model.Config)
  646. if err = s.dao.DB.First(&conf, ID).Error; err != nil {
  647. log.Error("Value() error(%v)", err)
  648. }
  649. return
  650. }
  651. //ConfigsByTree get Config by Config name.
  652. func (s *Service) ConfigsByTree(treeID int64, env, zone, name string) (confs []*model.Config, err error) {
  653. var app *model.App
  654. if app, err = s.AppByTree(treeID, env, zone); err != nil {
  655. return
  656. }
  657. if err = s.dao.DB.Order("id desc").Limit(10).Find(&confs, "name = ? and app_id = ?", name, app.ID).Error; err != nil {
  658. if err == sql.ErrNoRows {
  659. err = nil
  660. }
  661. return
  662. }
  663. return
  664. }
  665. // NamesByAppTree get configs by app name.
  666. func (s *Service) NamesByAppTree(appName, env, zone string, treeID int64) (names []string, err error) {
  667. var (
  668. app *model.App
  669. confs []*model.Config
  670. )
  671. if app, err = s.AppByTree(treeID, env, zone); err != nil {
  672. if err == ecode.NothingFound {
  673. err = s.CreateApp(appName, env, zone, treeID)
  674. return
  675. }
  676. }
  677. if err = s.dao.DB.Select("name").Where("app_id = ?", app.ID).Order("id desc").Group("name").Find(&confs).Error; err != nil {
  678. log.Error("NamesByAppName(%v) error(%v)", app.ID, err)
  679. if err == sql.ErrNoRows {
  680. err = nil
  681. }
  682. return
  683. }
  684. for _, conf := range confs {
  685. names = append(names, conf.Name)
  686. }
  687. return
  688. }
  689. //Diff get value by Config ID.
  690. func (s *Service) Diff(ID, BuildID int64) (data *model.Config, err error) {
  691. var tmpID int64
  692. var idArr []string
  693. conf := new(model.Config)
  694. if err = s.dao.DB.First(&conf, ID).Error; err != nil {
  695. log.Error("Diff() config_id(%v) error(%v)", ID, err)
  696. return
  697. }
  698. config := []*model.Config{}
  699. if err = s.dao.DB.Where("`app_id` = ? and `name` = ? and `state` = 2", conf.AppID, conf.Name).Order("id desc").Find(&config).Error; err != nil {
  700. log.Error("Diff() app_id(%v) name(%v) error(%v)", conf.AppID, conf.Name, err)
  701. return
  702. }
  703. build := &model.Build{}
  704. if err = s.dao.DB.First(build, BuildID).Error; err != nil && err != gorm.ErrRecordNotFound {
  705. log.Error("Diff() build_id(%v) error(%v)", BuildID, err)
  706. return
  707. }
  708. err = nil
  709. if build.ID > 0 {
  710. tag := &model.Tag{}
  711. if err = s.dao.DB.First(tag, build.TagID).Error; err != nil {
  712. log.Error("Diff() tag_id(%v) error(%v)", build.TagID, err)
  713. return
  714. }
  715. idArr = strings.Split(tag.ConfigIDs, ",")
  716. }
  717. if len(idArr) > 0 {
  718. for _, val := range config {
  719. for _, vv := range idArr {
  720. tmpID, _ = strconv.ParseInt(vv, 10, 64)
  721. if tmpID == val.ID {
  722. data = val
  723. return
  724. }
  725. }
  726. }
  727. }
  728. for _, val2 := range config {
  729. if val2.ID < ID {
  730. data = val2
  731. return
  732. }
  733. }
  734. data = conf
  735. return
  736. }
  737. //ConfigDel config is delete.
  738. func (s *Service) ConfigDel(ID int64) (err error) {
  739. conf := &model.Config{}
  740. if err = s.dao.DB.First(conf, ID).Error; err != nil {
  741. log.Error("ConfigDel first id(%v) error(%v)", ID, err)
  742. return
  743. }
  744. confs := []*model.Config{}
  745. if err = s.dao.DB.Where("app_id = ? and name = ?", conf.AppID, conf.Name).Find(&confs).Error; err != nil {
  746. log.Error("ConfigDel find error(%v)", err)
  747. return
  748. }
  749. build := []*model.Build{}
  750. if err = s.dao.DB.Where("app_id = ?", conf.AppID).Find(&build).Error; err != nil {
  751. log.Error("ConfigDel find app_id(%v) error(%v)", conf.AppID, err)
  752. return
  753. }
  754. for _, val := range build {
  755. tag := &model.Tag{}
  756. if err = s.dao.DB.Where("id = ?", val.TagID).First(tag).Error; err != nil {
  757. log.Error("ConfigDel first tag_id(%v) error(%v)", val.TagID, err)
  758. return
  759. }
  760. arr := strings.Split(tag.ConfigIDs, ",")
  761. for _, vv := range arr {
  762. for _, vvv := range confs {
  763. if vv == strconv.FormatInt(vvv.ID, 10) {
  764. err = ecode.NothingFound
  765. return
  766. }
  767. }
  768. }
  769. }
  770. ups := map[string]interface{}{
  771. "is_delete": 1,
  772. "state": 2,
  773. }
  774. if err = s.dao.DB.Model(conf).Where("id = ?", ID).Updates(ups).Error; err != nil {
  775. log.Error("ConfigDel updates error(%v)", err)
  776. }
  777. return
  778. }
  779. //BuildConfigInfos configRefs.
  780. func (s *Service) BuildConfigInfos(appName, env, zone string, buildID, treeID int64) (res map[string][]*model.ConfigRefs, err error) {
  781. var (
  782. allConfs []*model.Config
  783. buildConfs []*model.Config
  784. num int
  785. ok bool
  786. ref *model.ConfigRefs
  787. )
  788. if allConfs, err = s.ConfigsByAppName(appName, env, zone, treeID, model.ConfigEnd); err != nil {
  789. return
  790. }
  791. if buildID != 0 {
  792. if buildConfs, err = s.ConfigsByBuildID(buildID); err != nil {
  793. return
  794. }
  795. }
  796. tmpMap := make(map[string]int)
  797. tmpBuildConfs := make(map[string]map[int64]struct{})
  798. refs := make(map[string]*model.ConfigRefs)
  799. for _, conf := range allConfs {
  800. if num, ok = tmpMap[conf.Name]; !ok {
  801. ref = new(model.ConfigRefs)
  802. refs[conf.Name] = ref
  803. tmpMap[conf.Name] = num
  804. } else {
  805. ref = refs[conf.Name]
  806. }
  807. if num <= 20 {
  808. ref.Configs = append(ref.Configs, &model.ConfigRef{ID: conf.ID, Mark: conf.Mark, IsDelete: conf.IsDelete})
  809. tmpMap[conf.Name] = num + 1
  810. if tmpBuildConfs[conf.Name] == nil {
  811. tmpBuildConfs[conf.Name] = make(map[int64]struct{})
  812. }
  813. tmpBuildConfs[conf.Name][conf.ID] = struct{}{}
  814. } else {
  815. for _, bconf := range buildConfs {
  816. if bconf.Name == conf.Name {
  817. if _, ok = tmpBuildConfs[conf.Name][bconf.ID]; !ok {
  818. tmpBuildConfs[conf.Name][bconf.ID] = struct{}{}
  819. ref.Configs = append(ref.Configs, &model.ConfigRef{ID: bconf.ID, Mark: bconf.Mark, IsDelete: bconf.IsDelete})
  820. }
  821. break
  822. }
  823. }
  824. }
  825. if ref.Ref != nil {
  826. continue
  827. }
  828. for _, bconf := range buildConfs {
  829. if bconf.Name == conf.Name {
  830. ref.Ref = &model.ConfigRef{ID: bconf.ID, Mark: bconf.Mark, IsDelete: bconf.IsDelete}
  831. break
  832. }
  833. }
  834. }
  835. res = make(map[string][]*model.ConfigRefs)
  836. var tp int64
  837. var IsDelete int64
  838. capacity := len(refs)
  839. res["new"] = make([]*model.ConfigRefs, 0, capacity)
  840. res["nothing"] = make([]*model.ConfigRefs, 0, capacity)
  841. res["notused"] = make([]*model.ConfigRefs, 0, capacity)
  842. for k, v := range refs {
  843. v.Name = k
  844. IsDelete = 0
  845. for i, tv := range v.Configs {
  846. if tv.IsDelete == 1 && tv.ID > IsDelete {
  847. IsDelete = tv.ID
  848. v.Configs = v.Configs[:i]
  849. }
  850. }
  851. v.DeleteMAX = IsDelete
  852. if len(v.Configs) == 0 {
  853. continue
  854. }
  855. if v.Ref != nil {
  856. tp = 0
  857. for _, vv := range v.Configs {
  858. if vv.ID > v.Ref.ID {
  859. tp = vv.ID
  860. }
  861. }
  862. if tp > 0 {
  863. res["new"] = append(res["new"], v)
  864. } else {
  865. res["nothing"] = append(res["nothing"], v)
  866. }
  867. } else {
  868. res["notused"] = append(res["notused"], v)
  869. }
  870. }
  871. return
  872. }
  873. // GetConfigs ...
  874. func (s *Service) GetConfigs(ids []int64, name string) (configs []*model.Config, err error) {
  875. if err = s.dao.DB.Where("name = ? AND id in (?)", name, ids).Find(&configs).Error; err != nil {
  876. log.Error("GetConfigs error(%v)", err)
  877. }
  878. return
  879. }
  880. // GetConfig ...
  881. func (s *Service) GetConfig(ids []int64, name string) (config *model.Config, err error) {
  882. config = new(model.Config)
  883. if err = s.dao.DB.Where("name = ? AND id in (?)", name, ids).First(config).Error; err != nil {
  884. log.Error("GetConfigs error(%v)", err)
  885. }
  886. return
  887. }