Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions src/core/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@ import (
"net/url"
"os"
"os/signal"
"strconv"
"strings"
"syscall"
"time"

"github.com/beego/beego/v2/server/web"

"github.com/goharbor/harbor/src/common"
"github.com/goharbor/harbor/src/common/dao"
common_http "github.com/goharbor/harbor/src/common/http"
configCtl "github.com/goharbor/harbor/src/controller/config"
Expand Down Expand Up @@ -222,6 +224,11 @@ func main() {
log.Error(err)
}

// Allow user to disable writing audit log to db by env while initialize
if err := initSkipAuditDBbyEnv(ctx); err != nil {
log.Errorf("Failed to initialize SkipAuditDB by ENV: %v", err)
}

// Init API handler
if err := api.Init(); err != nil {
log.Fatalf("Failed to initialize API handlers with error: %s", err.Error())
Expand Down Expand Up @@ -356,3 +363,34 @@ func getDefaultScannerName() string {
}
return ""
}

func initSkipAuditDBbyEnv(ctx context.Context) error {
var err error
skipAuditEnv := false
s := os.Getenv("SKIP_LOG_AUDIT_DATABASE")
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

suggest to add _INIT suffix so that it can be self explained.

if s != "" {
skipAuditEnv, err = strconv.ParseBool(s)
if err != nil {
log.Warningf("Failed to parse SKIP_LOG_AUDIT_DATABASE to bool with error: %v, Will use SKIP_LOG_AUDIT_DATABASE env as false", err)
}
}
log.Debugf("get SKIP_LOG_AUDIT_DATABASE from Env is %v", skipAuditEnv)

// get from db
mgr := config.GetCfgManager(ctx)
cfg, err := mgr.GetItemFromDriver(ctx, common.SkipAuditLogDatabase)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It can use the mgr.Get(), if the value is not set, this method will return a pre-defined error.

Copy link
Contributor Author

@MinerYang MinerYang Sep 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mgr.Get() get the k-v from the store map instead of the db driver directly. And it will always has a default values once cfgValues loaded

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should implement the function to check if k = common.SkipAuditLogDatabase exists in the properties table. not GetItermFromDriver()

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For sure I could implement either check the key existence in the db or like now return k-v from db.
However I think get a k-v from db can be more generically used in the future compare to return the key existence bool value solely.

if err != nil {
return err
}
// if key not exist in the db, set default ENV value
if val, ok := cfg[common.SkipAuditLogDatabase]; !ok {
log.Debugf("key SkipAuditLogDatabase do not exist in the db, will initialize as %v", skipAuditEnv)
cfg[common.SkipAuditLogDatabase] = skipAuditEnv
if err := mgr.UpdateConfig(ctx, cfg); err != nil {
return err
}
} else {
log.Debugf("key SkipAuditLogDatabase aleady exist in the db with value %v", val)
}
return nil
}
1 change: 1 addition & 0 deletions src/lib/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ type Manager interface {
Set(ctx context.Context, key string, value any)
Save(ctx context.Context) error
Get(ctx context.Context, key string) *metadata.ConfigureValue
GetItemFromDriver(ctx context.Context, key string) (map[string]any, error)
UpdateConfig(ctx context.Context, cfgs map[string]any) error
GetUserCfgs(ctx context.Context) map[string]any
ValidateCfg(ctx context.Context, cfgs map[string]any) error
Expand Down
5 changes: 5 additions & 0 deletions src/pkg/config/db/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ func (d *Cache) Save(ctx context.Context, cfg map[string]any) error {
return nil
}

// Get - delegate to driver
func (d *Cache) Get(ctx context.Context, key string) (map[string]any, error) {
return d.driver.Get(ctx, key)
}

// NewCacheDriver returns driver with cache
func NewCacheDriver(cache cache.Cache, driver store.Driver) store.Driver {
return &Cache{
Expand Down
18 changes: 18 additions & 0 deletions src/pkg/config/db/dao/dao.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/goharbor/harbor/src/lib/config/models"
"github.com/goharbor/harbor/src/lib/errors"
"github.com/goharbor/harbor/src/lib/orm"
"github.com/goharbor/harbor/src/lib/q"
)

// DAO the dao for configure items
Expand All @@ -30,6 +31,8 @@ type DAO interface {
GetConfigEntries(ctx context.Context) ([]*models.ConfigEntry, error)
// SaveConfigEntries save configure items provided
SaveConfigEntries(ctx context.Context, entries []models.ConfigEntry) error
// GetConfigItem get configure item by key
GetConfigItem(ctx context.Context, query *q.Query) ([]*models.ConfigEntry, error)
}

type dao struct {
Expand Down Expand Up @@ -59,6 +62,21 @@ func (d *dao) GetConfigEntries(ctx context.Context) ([]*models.ConfigEntry, erro
return p, nil
}

// GetConfigItem get configure item by query
func (d *dao) GetConfigItem(ctx context.Context, query *q.Query) ([]*models.ConfigEntry, error) {
query = q.MustClone(query)
qs, err := orm.QuerySetter(ctx, &models.ConfigEntry{}, query)
if err != nil {
return nil, err
}
var configs []*models.ConfigEntry
if _, err := qs.All(&configs); err != nil {
return nil, err
}
return configs, nil

}

func (d *dao) SaveConfigEntries(ctx context.Context, entries []models.ConfigEntry) error {
o, err := orm.FromContext(ctx)
if err != nil {
Expand Down
16 changes: 16 additions & 0 deletions src/pkg/config/db/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import (
"github.com/goharbor/harbor/src/lib/config/models"
"github.com/goharbor/harbor/src/lib/encrypt"
"github.com/goharbor/harbor/src/lib/log"
"github.com/goharbor/harbor/src/lib/q"
"github.com/goharbor/harbor/src/pkg/config/db/dao"
)

Expand Down Expand Up @@ -84,3 +85,18 @@ func (d *Database) Save(ctx context.Context, cfgs map[string]any) error {
}
return d.cfgDAO.SaveConfigEntries(ctx, configEntries)
}

// Get - Get config item from db
func (d *Database) Get(ctx context.Context, key string) (map[string]any, error) {
resultMap := map[string]any{}
configEntries, err := d.cfgDAO.GetConfigItem(ctx, q.New(q.KeyWords{"k": key}))
if err != nil {
log.Debugf("get config db error: %v", err)
return resultMap, err
}
// convert to map if there's any record
for _, item := range configEntries {
resultMap[item.Key] = item.Value
}
return resultMap, nil
}
6 changes: 6 additions & 0 deletions src/pkg/config/inmemory/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ package inmemory

import (
"context"
"errors"
"maps"
"sync"

Expand Down Expand Up @@ -54,6 +55,11 @@ func (d *Driver) Save(_ context.Context, cfg map[string]any) error {
return nil
}

// TODO
func (d *Driver) Get(ctx context.Context, key string) (map[string]any, error) {
return nil, errors.ErrUnsupported
}

// NewInMemoryManager create a manager for unit testing, doesn't involve database or REST
func NewInMemoryManager() *config.CfgManager {
manager := &config.CfgManager{Store: store.NewConfigStore(&Driver{cfgMap: map[string]any{}})}
Expand Down
4 changes: 4 additions & 0 deletions src/pkg/config/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,10 @@ func (c *CfgManager) UpdateConfig(ctx context.Context, cfgs map[string]any) erro
return c.Store.Update(ctx, cfgs)
}

func (c *CfgManager) GetItemFromDriver(ctx context.Context, key string) (map[string]any, error) {
return c.Store.GetFromDriver(ctx, key)
}

// ValidateCfg validate config by metadata. return the first error if exist.
func (c *CfgManager) ValidateCfg(ctx context.Context, cfgs map[string]any) error {
for key, value := range cfgs {
Expand Down
5 changes: 5 additions & 0 deletions src/pkg/config/rest/rest.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,8 @@ func (h *Driver) Load(_ context.Context) (map[string]any, error) {
func (h *Driver) Save(_ context.Context, cfg map[string]any) error {
return h.client.Put(h.configRESTURL, cfg)
}

// TODO
func (d *Driver) Get(ctx context.Context, key string) (map[string]any, error) {
return nil, errors.ErrUnsupported
}
2 changes: 2 additions & 0 deletions src/pkg/config/store/driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,6 @@ type Driver interface {
Load(ctx context.Context) (map[string]any, error)
// Save - save config item into config driver
Save(ctx context.Context, cfg map[string]any) error
// Load - load config item from config driver
Get(ctx context.Context, key string) (map[string]any, error)
}
11 changes: 11 additions & 0 deletions src/pkg/config/store/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,17 @@ func (c *ConfigStore) Get(key string) (*metadata.ConfigureValue, error) {
return nil, metadata.ErrValueNotSet
}

func (c *ConfigStore) GetFromDriver(ctx context.Context, key string) (map[string]any, error) {
if c.cfgDriver == nil {
return nil, errors.New("failed to load store, cfgDriver is nil")
}
cfgs, err := c.cfgDriver.Get(ctx, key)
if err != nil {
return nil, err
}
return cfgs, nil
}

// GetAnyType get any type for config items
func (c *ConfigStore) GetAnyType(key string) (any, error) {
if value, ok := c.cfgValues.Load(key); ok {
Expand Down
30 changes: 30 additions & 0 deletions src/testing/lib/config/manager.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading