mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-23 10:45:45 +01:00
Fix issue of detecting configuration changes
This commit is contained in:
parent
6f2ff672c4
commit
db58ca673d
47
src/common/notifier/config_watcher.go
Normal file
47
src/common/notifier/config_watcher.go
Normal 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
|
||||||
|
}
|
57
src/common/notifier/config_watcher_test.go
Normal file
57
src/common/notifier/config_watcher_test.go
Normal 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -129,6 +129,7 @@ func ParseTimeStamp(timestamp string) (*time.Time, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//ConvertMapToStruct is used to fill the specified struct with map.
|
//ConvertMapToStruct is used to fill the specified struct with map.
|
||||||
|
//Only support the exported fields.
|
||||||
func ConvertMapToStruct(object interface{}, valuesInMap map[string]interface{}) error {
|
func ConvertMapToStruct(object interface{}, valuesInMap map[string]interface{}) error {
|
||||||
if object == nil {
|
if object == nil {
|
||||||
return fmt.Errorf("nil struct is not supported")
|
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 {
|
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
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -192,7 +192,9 @@ func (c *ConfigAPI) Put() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Everything is ok, detect the configurations to confirm if the option we are caring is changed.
|
//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
|
// Reset system configurations
|
||||||
|
@ -17,11 +17,9 @@ package api
|
|||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
"reflect"
|
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@ -501,33 +499,7 @@ func transformVulnerabilities(layerWithVuln *models.ClairLayerEnvelope) []*model
|
|||||||
}
|
}
|
||||||
|
|
||||||
//Watch the configuration changes.
|
//Watch the configuration changes.
|
||||||
|
//Wrap the same method in common utils.
|
||||||
func watchConfigChanges(cfg map[string]interface{}) error {
|
func watchConfigChanges(cfg map[string]interface{}) error {
|
||||||
if cfg == nil {
|
return notifier.WatchConfigChanges(cfg)
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user