0
Fork 0
mirror of https://github.com/project-zot/zot.git synced 2024-12-16 21:56:37 -05:00
zot/pkg/api/config/config.go

219 lines
5.2 KiB
Go
Raw Normal View History

package config
2019-06-20 18:36:40 -05:00
import (
"fmt"
"time"
2019-08-15 11:34:54 -05:00
"github.com/getlantern/deepcopy"
2021-05-21 15:47:28 -05:00
distspec "github.com/opencontainers/distribution-spec/specs-go"
"github.com/spf13/viper"
"zotregistry.io/zot/errors"
extconf "zotregistry.io/zot/pkg/extensions/config"
"zotregistry.io/zot/pkg/log"
"zotregistry.io/zot/pkg/storage"
2019-06-20 18:36:40 -05:00
)
var (
Commit string // nolint: gochecknoglobals
BinaryType string // nolint: gochecknoglobals
GoVersion string // nolint: gochecknoglobals
)
2019-06-20 18:36:40 -05:00
type StorageConfig struct {
RootDirectory string
GC bool
Dedupe bool
Commit bool
GCDelay time.Duration
GCInterval time.Duration
StorageDriver map[string]interface{} `mapstructure:",omitempty"`
2019-06-20 18:36:40 -05:00
}
type TLSConfig struct {
Cert string
Key string
CACert string
}
type AuthHTPasswd struct {
Path string
}
type AuthConfig struct {
FailDelay int
HTPasswd AuthHTPasswd
2019-08-15 11:34:54 -05:00
LDAP *LDAPConfig
Bearer *BearerConfig
}
type BearerConfig struct {
Realm string
Service string
Cert string
2019-06-20 18:36:40 -05:00
}
type MethodRatelimitConfig struct {
Method string
Rate int
}
type RatelimitConfig struct {
Rate *int // requests per second
Methods []MethodRatelimitConfig `mapstructure:",omitempty"`
}
2019-06-20 18:36:40 -05:00
type HTTPConfig struct {
Address string
Port string
AllowOrigin string // comma separated
TLS *TLSConfig
Auth *AuthConfig
RawAccessControl map[string]interface{} `mapstructure:"accessControl,omitempty"`
Realm string
AllowReadAccess bool `mapstructure:",omitempty"`
ReadOnly bool `mapstructure:",omitempty"`
Ratelimit *RatelimitConfig `mapstructure:",omitempty"`
2019-06-20 18:36:40 -05:00
}
2019-08-15 11:34:54 -05:00
type LDAPConfig struct {
Port int
Insecure bool
StartTLS bool // if !Insecure, then StartTLS or LDAPs
SkipVerify bool
SubtreeSearch bool
Address string
BindDN string
BindPassword string
BaseDN string
UserAttribute string
CACert string
}
2019-06-20 18:36:40 -05:00
type LogConfig struct {
Level string
Output string
Audit string
2019-06-20 18:36:40 -05:00
}
type GlobalStorageConfig struct {
Dedupe bool
GC bool
Commit bool
GCDelay time.Duration
GCInterval time.Duration
RootDirectory string
StorageDriver map[string]interface{} `mapstructure:",omitempty"`
SubPaths map[string]StorageConfig
}
type AccessControlConfig struct {
Repositories Repositories
AdminPolicy Policy
}
type Repositories map[string]PolicyGroup
type PolicyGroup struct {
Policies []Policy
DefaultPolicy []string
}
type Policy struct {
Users []string
Actions []string
}
2019-06-20 18:36:40 -05:00
type Config struct {
DistSpecVersion string `json:"distSpecVersion" mapstructure:"distSpecVersion"`
GoVersion string
Commit string
BinaryType string
AccessControl *AccessControlConfig
Storage GlobalStorageConfig
HTTP HTTPConfig
Log *LogConfig
Extensions *extconf.ExtensionConfig
2019-06-20 18:36:40 -05:00
}
func New() *Config {
2019-06-20 18:36:40 -05:00
return &Config{
DistSpecVersion: distspec.Version,
GoVersion: GoVersion,
Commit: Commit,
BinaryType: BinaryType,
Storage: GlobalStorageConfig{GC: true, GCDelay: storage.DefaultGCDelay, Dedupe: true},
HTTP: HTTPConfig{Address: "127.0.0.1", Port: "8080"},
Log: &LogConfig{Level: "debug"},
2019-08-15 11:34:54 -05:00
}
}
// Sanitize makes a sanitized copy of the config removing any secrets.
2019-08-15 11:34:54 -05:00
func (c *Config) Sanitize() *Config {
sanitizedConfig := &Config{}
if err := deepcopy.Copy(sanitizedConfig, c); err != nil {
panic(err)
}
if c.HTTP.Auth != nil && c.HTTP.Auth.LDAP != nil && c.HTTP.Auth.LDAP.BindPassword != "" {
sanitizedConfig.HTTP.Auth.LDAP = &LDAPConfig{}
if err := deepcopy.Copy(sanitizedConfig.HTTP.Auth.LDAP, c.HTTP.Auth.LDAP); err != nil {
2019-08-15 11:34:54 -05:00
panic(err)
}
sanitizedConfig.HTTP.Auth.LDAP.BindPassword = "******"
2019-08-15 11:34:54 -05:00
}
return sanitizedConfig
2019-08-15 11:34:54 -05:00
}
func (c *Config) Validate(log log.Logger) error {
2019-08-15 11:34:54 -05:00
// LDAP configuration
if c.HTTP.Auth != nil && c.HTTP.Auth.LDAP != nil {
l := c.HTTP.Auth.LDAP
if l.UserAttribute == "" {
log.Error().Str("userAttribute", l.UserAttribute).Msg("invalid LDAP configuration")
2019-08-15 11:34:54 -05:00
return errors.ErrLDAPConfig
}
2019-06-20 18:36:40 -05:00
}
2019-08-15 11:34:54 -05:00
return nil
2019-06-20 18:36:40 -05:00
}
// LoadAccessControlConfig populates config.AccessControl struct with values from config.
func (c *Config) LoadAccessControlConfig(viperInstance *viper.Viper) error {
if c.HTTP.RawAccessControl == nil {
return nil
}
c.AccessControl = &AccessControlConfig{}
c.AccessControl.Repositories = make(map[string]PolicyGroup)
for policy := range c.HTTP.RawAccessControl {
var policies []Policy
var policyGroup PolicyGroup
if policy == "adminpolicy" {
adminPolicy := viperInstance.GetStringMapStringSlice("http::accessControl::adminPolicy")
c.AccessControl.AdminPolicy.Actions = adminPolicy["actions"]
c.AccessControl.AdminPolicy.Users = adminPolicy["users"]
continue
}
err := viperInstance.UnmarshalKey(fmt.Sprintf("http::accessControl::%s::policies", policy), &policies)
if err != nil {
return err
}
defaultPolicy := viperInstance.GetStringSlice(fmt.Sprintf("http::accessControl::%s::defaultPolicy", policy))
policyGroup.Policies = policies
policyGroup.DefaultPolicy = defaultPolicy
c.AccessControl.Repositories[policy] = policyGroup
}
return nil
}