1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
package registry
import (
"fmt"
"os"
"time"
"github.com/argoproj-labs/argocd-image-updater/registry-scanner/pkg/log"
"gopkg.in/yaml.v2"
)
// RegistryConfiguration represents a single repository configuration for being
// unmarshaled from YAML.
type RegistryConfiguration struct {
Name string `yaml:"name"`
ApiURL string `yaml:"api_url"`
Ping bool `yaml:"ping,omitempty"`
Credentials string `yaml:"credentials,omitempty"`
CredsExpire time.Duration `yaml:"credsexpire,omitempty"`
TagSortMode string `yaml:"tagsortmode,omitempty"`
Prefix string `yaml:"prefix,omitempty"`
Insecure bool `yaml:"insecure,omitempty"`
DefaultNS string `yaml:"defaultns,omitempty"`
Limit int `yaml:"limit,omitempty"`
IsDefault bool `yaml:"default,omitempty"`
}
// RegistryList contains multiple RegistryConfiguration items
type RegistryList struct {
Items []RegistryConfiguration `yaml:"registries"`
}
func clearRegistries() {
registryLock.Lock()
registries = make(map[string]*RegistryEndpoint)
registryLock.Unlock()
}
// LoadRegistryConfiguration loads a YAML-formatted registry configuration from
// a given file at path.
func LoadRegistryConfiguration(path string, clear bool) error {
registryBytes, err := os.ReadFile(path)
if err != nil {
return err
}
registryList, err := ParseRegistryConfiguration(string(registryBytes))
if err != nil {
return err
}
if clear {
clearRegistries()
}
haveDefault := false
for _, reg := range registryList.Items {
tagSortMode := TagListSortFromString(reg.TagSortMode)
if tagSortMode != TagListSortUnsorted {
log.Warnf("Registry %s has tag sort mode set to %s, meta data retrieval will be disabled for this registry.", reg.ApiURL, tagSortMode)
}
ep := NewRegistryEndpoint(reg.Prefix, reg.Name, reg.ApiURL, reg.Credentials, reg.DefaultNS, reg.Insecure, tagSortMode, reg.Limit, reg.CredsExpire)
if reg.IsDefault {
if haveDefault {
dep := GetDefaultRegistry()
if dep == nil {
panic("unexpected: default registry should be set, but is not")
}
return fmt.Errorf("cannot set registry %s as default - only one default registry allowed, currently set to %s", ep.RegistryPrefix, dep.RegistryPrefix)
}
}
if err := AddRegistryEndpoint(ep); err != nil {
return err
}
if reg.IsDefault {
SetDefaultRegistry(ep)
haveDefault = true
}
}
log.Infof("Loaded %d registry configurations from %s", len(registryList.Items), path)
return nil
}
// Parses a registry configuration from a YAML input string and returns a list
// of registries.
func ParseRegistryConfiguration(yamlSource string) (RegistryList, error) {
var regList RegistryList
var defaultPrefixFound = ""
err := yaml.UnmarshalStrict([]byte(yamlSource), ®List)
if err != nil {
return RegistryList{}, err
}
// validate the parsed list
for _, registry := range regList.Items {
if registry.Name == "" {
err = fmt.Errorf("registry name is missing for entry %v", registry)
} else if registry.ApiURL == "" {
err = fmt.Errorf("API URL must be specified for registry %s", registry.Name)
} else if registry.Prefix == "" {
if defaultPrefixFound != "" {
err = fmt.Errorf("there must be only one default registry (already is %s), %s needs a prefix", defaultPrefixFound, registry.Name)
} else {
defaultPrefixFound = registry.Name
}
}
if err == nil {
if tls := TagListSortFromString(registry.TagSortMode); tls == TagListSortUnknown {
err = fmt.Errorf("unknown tag sort mode for registry %s: %s", registry.Name, registry.TagSortMode)
}
}
}
if err != nil {
return RegistryList{}, err
}
return regList, nil
}
// RestRestoreDefaultRegistryConfiguration restores the registry configuration
// to the default values.
func RestoreDefaultRegistryConfiguration() {
registryLock.Lock()
defer registryLock.Unlock()
defaultRegistry = nil
registries = make(map[string]*RegistryEndpoint)
for k, v := range registryTweaks {
registries[k] = v.DeepCopy()
if v.IsDefault {
SetDefaultRegistry(registries[k])
}
}
}
|