Example #1
0
func cloneConfigs(app *models.App, configs []*models.Config, userKey string) (err error) {
	newDataVersion := genNewDataVersion(memConfDataVersion)

	s := models.NewSession()
	defer s.Close()
	if err = s.Begin(); err != nil {
		return
	}

	if _, err = updateApp(app, newDataVersion, s); err != nil {
		return
	}

	for _, config := range configs {
		if _, err = updateConfig(config, userKey, newDataVersion, s); err != nil {
			s.Rollback()
			return
		}
	}

	_app, err := models.GetAppByKey(s, app.Key)
	if err != nil {
		s.Rollback()
		return err
	}

	node, err := models.GetNodeByURL(s, conf.ClientAddr)
	if err != nil {
		s.Rollback()
		return err
	}

	if err = s.Commit(); err != nil {
		s.Rollback()
		return
	}

	*app = *_app

	updateMemConf(app, newDataVersion, node)
	for _, config := range configs {
		updateMemConf(config, newDataVersion, node)
	}

	return
}
Example #2
0
func updateMemConf(i interface{}, newDataVersion *models.DataVersion, node *models.Node, auxData ...interface{}) {
	memConfMux.Lock()
	defer memConfMux.Unlock()

	switch m := i.(type) {
	case *models.User:
		oldUser := memConfUsers[m.Key]
		if oldUser != nil {
			memConfUsersByName[m.Name] = nil
		}
		memConfUsers[m.Key] = m
		memConfUsersByName[m.Name] = m

	case *models.App:
		oldApp := memConfApps[m.Key]
		if oldApp != nil {
			memConfAppsByName[oldApp.Name] = nil
		}
		memConfApps[m.Key] = m
		memConfAppsByName[m.Name] = m

	case *models.Config:
		isSysConf := isSysConfType(m.AppKey)
		if !isSysConf && len(auxData) > 0 {
			toUpdateApps := auxData[0].([]*models.App)
			app, err := models.GetAppByKey(nil, m.AppKey)
			if err != nil {
				panic("Failed to load app info from db")
			}
			memConfApps[m.AppKey] = app
			for _, _app := range toUpdateApps {
				_app.DataSign = app.DataSign
			}
		}

		oldConfig := memConfRawConfigs[m.Key]
		if oldConfig == nil {
			memConfAppConfigs[m.AppKey] = append(memConfAppConfigs[m.AppKey], transConfig(m))
		} else {
			for ix, _config := range memConfAppConfigs[m.AppKey] {
				if m.Key == _config.Key {
					memConfAppConfigs[m.AppKey][ix] = transConfig(m)
					break
				}
			}
		}

		memConfRawConfigs[m.Key] = m

	case *models.WebHook:
		oldHookIdx := auxData[0].(int)
		if oldHookIdx == -1 {
			if m.Scope == models.WEBHOOK_SCOPE_GLOBAL {
				memConfGlobalWebHooks = append(memConfGlobalWebHooks, m)
			} else if m.Scope == models.WEBHOOK_SCOPE_APP {
				memConfAppWebHooks[m.AppKey] = append(memConfAppWebHooks[m.AppKey], m)
			}

		} else {
			if m.Scope == models.WEBHOOK_SCOPE_GLOBAL {
				memConfGlobalWebHooks[oldHookIdx] = m
			} else if m.Scope == models.WEBHOOK_SCOPE_APP {
				memConfAppWebHooks[m.AppKey][oldHookIdx] = m
			}
		}
	}

	memConfDataVersion = newDataVersion
	if node != nil {
		memConfNodes[node.URL] = node
	}
}
Example #3
0
func updateConfig(config *models.Config, userKey string, newDataVersion *models.DataVersion, ms *models.Session) (*models.Config, error) {
	var s *models.Session

	if ms != nil {
		s = ms
	} else {
		s = models.NewSession()
		defer s.Close()
		if err := s.Begin(); err != nil {
			s.Rollback()
			return nil, err
		}
	}

	isSysConf := isSysConfType(config.AppKey)

	node := *memConfNodes[conf.ClientAddr]
	oldConfig := memConfRawConfigs[config.Key]

	app, err := models.GetAppByKey(s, config.AppKey)
	if err != nil {
		return nil, err
	}

	if newDataVersion == nil {
		newDataVersion = genNewDataVersion(memConfDataVersion)
	}

	if err := updateNodeDataVersion(s, &node, newDataVersion); err != nil {
		if ms == nil {
			s.Rollback()
		}
		return nil, err
	}

	var configHistory *models.ConfigUpdateHistory

	if oldConfig == nil {
		configHistory = &models.ConfigUpdateHistory{
			Id:         utils.GenerateKey(),
			ConfigKey:  config.Key,
			K:          config.K,
			OldV:       "",
			OldVType:   "",
			NewV:       config.V,
			NewVType:   config.VType,
			Kind:       models.CONFIG_UPDATE_KIND_NEW,
			UserKey:    userKey,
			CreatedUTC: utils.GetNowSecond(),
		}
		if err := models.InsertRow(s, configHistory); err != nil {
			if ms == nil {
				s.Rollback()
			}
			return nil, err
		}

		config.LastUpdateId = configHistory.Id
		if err := models.InsertRow(s, config); err != nil {
			if ms == nil {
				s.Rollback()
			}
			return nil, err
		}

		if !isSysConf {
			app.KeyCount++
			app.LastUpdateUTC = configHistory.CreatedUTC
			app.LastUpdateId = configHistory.Id
			app.UpdateTimes++
		}

	} else {
		kind := models.CONFIG_UPDATE_KIND_UPDATE
		if config.Status != oldConfig.Status {
			if config.Status == models.CONF_STATUS_ACTIVE {
				kind = models.CONFIG_UPDATE_KIND_RECOVER
			} else {
				kind = models.CONFIG_UPDATE_KIND_HIDE
			}
		}

		configHistory = &models.ConfigUpdateHistory{
			Id:         utils.GenerateKey(),
			ConfigKey:  config.Key,
			K:          config.K,
			OldV:       oldConfig.V,
			OldVType:   oldConfig.VType,
			NewV:       config.V,
			NewVType:   config.VType,
			Kind:       kind,
			UserKey:    userKey,
			CreatedUTC: utils.GetNowSecond(),
		}
		if err := models.InsertRow(s, configHistory); err != nil {
			if ms == nil {
				s.Rollback()
			}
			return nil, err
		}

		config.UpdateTimes++
		config.LastUpdateId = configHistory.Id
		if err := models.UpdateDBModel(s, config); err != nil {
			if ms == nil {
				s.Rollback()
			}
			return nil, err
		}
		if !isSysConf {
			app.LastUpdateUTC = configHistory.CreatedUTC
			app.LastUpdateId = configHistory.Id
			app.UpdateTimes++
		}
	}

	var toUpdateApps []*models.App
	if !isSysConf {
		newDataSign := utils.GenerateKey()
		app.DataSign = newDataSign
		if err := models.UpdateDBModel(s, app); err != nil {
			if ms == nil {
				s.Rollback()
			}
			return nil, err
		}

		if app.Type == models.APP_TYPE_TEMPLATE {
			for _, _app := range memConfApps {
				if _app.Key == config.AppKey {
					continue
				}
				for _, _config := range memConfAppConfigs[_app.Key] {
					if _config.VType == models.CONF_V_TYPE_TEMPLATE && _config.V == config.AppKey {
						// this app has a config refer to this template app
						toUpdateApps = append(toUpdateApps, _app)
						break
					}
				}
			}
		}

		for _, app := range toUpdateApps {
			_app := *app
			_app.DataSign = newDataSign
			if err := models.UpdateDBModel(s, &_app); err != nil {
				if ms == nil {
					s.Rollback()
				}
				return nil, err
			}
		}
	}

	if ms == nil {
		if err := s.Commit(); err != nil {
			s.Rollback()
			return nil, err
		}

		if !isSysConf {
			go TriggerWebHooks(configHistory, app)
		} else {
			go TriggerWebHooks(configHistory, &models.App{Key: config.Key, Name: config.Key})
		}

		updateMemConf(config, newDataVersion, &node, toUpdateApps)
	}

	return config, nil
}