Fix issue of detecting configuration changes

This commit is contained in:
Steven Zou 2017-07-17 17:39:41 +08:00
parent 6f2ff672c4
commit db58ca673d
5 changed files with 111 additions and 32 deletions

View File

@ -0,0 +1,47 @@
package notifier
import (
"errors"
"reflect"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/utils"
)
//WatchConfigChanges is used to watch the configuration changes.
func WatchConfigChanges(cfg map[string]interface{}) error {
if cfg == nil {
return errors.New("Empty configurations")
}
//Currently only watch the scan all policy change.
if v, ok := cfg[ScanAllPolicyTopic]; ok {
if reflect.TypeOf(v).Kind() == reflect.Map {
policyCfg := &models.ScanAllPolicy{}
vMap := v.(map[string]interface{})
//Reset filed name.
if pv, yes := vMap["parameter"]; yes {
vMap["Parm"] = pv
delete(vMap, "parameter")
}
if err := utils.ConvertMapToStruct(policyCfg, vMap); err != nil {
return err
}
policyNotification := ScanPolicyNotification{
Type: policyCfg.Type,
DailyTime: 0,
}
if t, yes := policyCfg.Parm["daily_time"]; yes {
if reflect.TypeOf(t).Kind() == reflect.Int {
policyNotification.DailyTime = (int64)(t.(int))
}
}
return Publish(ScanAllPolicyTopic, policyNotification)
}
}
return nil
}

View File

@ -0,0 +1,57 @@
package notifier
import (
"encoding/json"
"strconv"
"strings"
"testing"
"time"
)
var jsonText = `
{
"scan_all_policy": {
"type": "daily",
"parameter": {
"daily_time": <PLACE_HOLDER>
}
}
}
`
func TestWatchConfiguration(t *testing.T) {
now := time.Now().UTC()
offset := (now.Hour()+1)*3600 + now.Minute()*60
jsonT := strings.Replace(jsonText, "<PLACE_HOLDER>", strconv.Itoa(offset), -1)
v := make(map[string]interface{})
if err := json.Unmarshal([]byte(jsonT), &v); err != nil {
t.Fatal(err)
}
if err := WatchConfigChanges(v); err != nil {
if !strings.Contains(err.Error(), "No handlers registered") {
t.Fatal(err)
}
}
}
var jsonText2 = `
{
"scan_all_policy": {
"type": "none"
}
}
`
func TestWatchConfiguration2(t *testing.T) {
v := make(map[string]interface{})
if err := json.Unmarshal([]byte(jsonText2), &v); err != nil {
t.Fatal(err)
}
if err := WatchConfigChanges(v); err != nil {
if !strings.Contains(err.Error(), "No handlers registered") {
t.Fatal(err)
}
}
}

View File

@ -129,6 +129,7 @@ func ParseTimeStamp(timestamp string) (*time.Time, error) {
}
//ConvertMapToStruct is used to fill the specified struct with map.
//Only support the exported fields.
func ConvertMapToStruct(object interface{}, valuesInMap map[string]interface{}) error {
if object == nil {
return fmt.Errorf("nil struct is not supported")
@ -139,7 +140,7 @@ func ConvertMapToStruct(object interface{}, valuesInMap map[string]interface{})
}
for k, v := range valuesInMap {
if err := setField(object, k, v); err != nil {
if err := setField(object, strings.Title(strings.ToLower(k)), v); err != nil {
return err
}
}

View File

@ -192,7 +192,9 @@ func (c *ConfigAPI) Put() {
}
//Everything is ok, detect the configurations to confirm if the option we are caring is changed.
watchConfigChanges(cfg)
if err := watchConfigChanges(cfg); err != nil {
log.Errorf("Failed to watch configuration change with error: %s\n", err)
}
}
// Reset system configurations

View File

@ -17,11 +17,9 @@ package api
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"reflect"
"sort"
"strings"
@ -501,33 +499,7 @@ func transformVulnerabilities(layerWithVuln *models.ClairLayerEnvelope) []*model
}
//Watch the configuration changes.
//Wrap the same method in common utils.
func watchConfigChanges(cfg map[string]interface{}) error {
if cfg == nil {
return errors.New("Empty configurations")
}
//Currently only watch the scan all policy change.
if v, ok := cfg[notifier.ScanAllPolicyTopic]; ok {
if reflect.TypeOf(v).Kind() == reflect.Map {
policyCfg := &models.ScanAllPolicy{}
if err := utils.ConvertMapToStruct(policyCfg, v.(map[string]interface{})); err != nil {
return err
}
policyNotification := notifier.ScanPolicyNotification{
Type: policyCfg.Type,
DailyTime: 0,
}
if t, yes := policyCfg.Parm["daily_time"]; yes {
if reflect.TypeOf(t).Kind() == reflect.Int {
policyNotification.DailyTime = (int64)(t.(int))
}
}
return notifier.Publish(notifier.ScanAllPolicyTopic, policyNotification)
}
}
return nil
return notifier.WatchConfigChanges(cfg)
}