Fix the import cycle issue

This commit is contained in:
Steven Zou 2017-07-07 20:12:01 +08:00
parent cadc1187c2
commit a0718385c1
5 changed files with 119 additions and 41 deletions

View File

@ -16,9 +16,11 @@ package utils
import (
"crypto/rand"
"errors"
"fmt"
"net"
"net/url"
"reflect"
"strconv"
"strings"
"time"
@ -125,3 +127,45 @@ func ParseTimeStamp(timestamp string) (*time.Time, error) {
t := time.Unix(i, 0)
return &t, nil
}
//ConvertMapToStruct is used to fill the specified struct with map.
func ConvertMapToStruct(object interface{}, valuesInMap map[string]interface{}) error {
if object == nil {
return fmt.Errorf("nil struct is not supported")
}
if reflect.TypeOf(object).Kind() != reflect.Ptr {
return fmt.Errorf("object should be referred by pointer")
}
for k, v := range valuesInMap {
if err := setField(object, k, v); err != nil {
return err
}
}
return nil
}
func setField(object interface{}, field string, value interface{}) error {
structValue := reflect.ValueOf(object).Elem()
structFieldValue := structValue.FieldByName(field)
if !structFieldValue.IsValid() {
return fmt.Errorf("No such field: %s in obj", field)
}
if !structFieldValue.CanSet() {
return fmt.Errorf("Cannot set value for field %s", field)
}
structFieldType := structFieldValue.Type()
val := reflect.ValueOf(value)
if structFieldType != val.Type() {
return errors.New("Provided value type didn't match object field type")
}
structFieldValue.Set(val)
return nil
}

View File

@ -190,6 +190,9 @@ func (c *ConfigAPI) Put() {
log.Errorf("failed to load configurations: %v", err)
c.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError))
}
//Everything is ok, detect the configurations to confirm if the option we are caring is changed.
watchConfigChanges(cfg)
}
// Reset system configurations

View File

@ -17,14 +17,17 @@ package api
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io/ioutil"
"net/http"
"reflect"
"sort"
"strings"
"github.com/vmware/harbor/src/common/dao"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/notifier"
"github.com/vmware/harbor/src/common/utils"
"github.com/vmware/harbor/src/common/utils/clair"
registry_error "github.com/vmware/harbor/src/common/utils/error"
@ -496,3 +499,35 @@ func transformVulnerabilities(layerWithVuln *models.ClairLayerEnvelope) []*model
}
return res
}
//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[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
}

36
src/ui/api/utils_test.go Normal file
View File

@ -0,0 +1,36 @@
package api
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.Fail()
}
if err := watchConfigChanges(v); err != nil {
if !strings.Contains(err.Error(), "No handlers registered") {
t.Fail()
}
}
}

View File

@ -20,17 +20,13 @@ import (
"fmt"
"net/http"
"os"
"reflect"
"strings"
"errors"
"github.com/vmware/harbor/src/adminserver/client"
"github.com/vmware/harbor/src/adminserver/client/auth"
"github.com/vmware/harbor/src/common"
comcfg "github.com/vmware/harbor/src/common/config"
"github.com/vmware/harbor/src/common/models"
"github.com/vmware/harbor/src/common/notifier"
"github.com/vmware/harbor/src/common/secret"
"github.com/vmware/harbor/src/common/utils/log"
"github.com/vmware/harbor/src/ui/projectmanager"
@ -149,15 +145,7 @@ func Reset() error {
// Upload uploads all system configurations to admin server
func Upload(cfg map[string]interface{}) error {
err := mg.Upload(cfg)
if err == nil {
//Watch configuration changes after updating.
if er := watchConfigChanges(cfg); er != nil {
log.Errorf("Error occurred when watching configuration changes: %s\n", er.Error())
}
}
return err
return mg.Upload(cfg)
}
// GetSystemCfg returns the system configurations
@ -412,31 +400,3 @@ func ScanAllPolicy() models.ScanAllPolicy {
func WithAdmiral() bool {
return len(AdmiralEndpoint()) > 0
}
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.Struct &&
reflect.TypeOf(v).String() == "models.ScanAllPolicy" {
policyCfg := v.(models.ScanAllPolicy)
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 = t.(int64)
}
}
return notifier.Publish(notifier.ScanAllPolicyTopic, policyNotification)
}
}
return nil
}