forked from rancher/fleet
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig.go
More file actions
277 lines (230 loc) · 9.98 KB
/
config.go
File metadata and controls
277 lines (230 loc) · 9.98 KB
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
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
// Package config implements the config for the fleet controller and agent
package config
import (
"context"
"encoding/json"
"sync"
"time"
fleet "github.com/rancher/fleet/pkg/apis/fleet.cattle.io/v1alpha1"
corev1 "github.com/rancher/wrangler/v3/pkg/generated/controllers/core/v1"
v1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"sigs.k8s.io/yaml"
"github.com/rancher/fleet/pkg/version"
)
const (
ManagerConfigName = "fleet-controller"
AgentConfigName = "fleet-agent"
AgentBootstrapConfigName = "fleet-agent-bootstrap"
AgentTLSModeStrict = "strict"
AgentTLSModeSystemStore = "system-store"
Key = "config"
// DefaultNamespace is the default for the system namespace, which
// contains the controller and agent
DefaultNamespace = "cattle-fleet-system"
LegacyDefaultNamespace = "fleet-system"
// ImportTokenSecretValuesKey is the key in the import token secret,
// which contains the values for cluster registration.
ImportTokenSecretValuesKey = "values"
// KubeConfigSecretValueKey is the key in the kubeconfig secret, which
// contains the kubeconfig for the downstream cluster.
KubeConfigSecretValueKey = "value"
// APIServerURLKey is the key which contains the API server URL of the
// upstream server. It is used in the controller config, the kubeconfig
// secret of a cluster, the cluster registration secret "import-NAME"
// and the fleet-agent-bootstrap secret.
APIServerURLKey = "apiServerURL"
// APIServerCAKey is the key which contains the CA of the upstream
// server.
APIServerCAKey = "apiServerCA"
// EnvVarWranglerCheckGVKErrorMapping is the env var name used to configure Wrangler's GVK error mapping.
EnvVarWranglerCheckGVKErrorMapping = "CATTLE_WRANGLER_CHECK_GVK_ERROR_MAPPING"
// Default secret name for git credentials, used as a fallback if no secret is referenced by an app.
DefaultGitCredentialsSecretName = "gitcredential" //nolint:gosec // this is a resource name
// Default secret name for oci storage,
// used as a fallback if no secret is specified by the user in the GitRepo.
DefaultOCIStorageSecretName = "ocistorage"
// ContentNameIndex is the name of the index for the content name label in bundle deployments
ContentNameIndex = "metadata.labels." + fleet.ContentNameLabel
// RepoNameIndex is the name of the index for the gitrepo name in bundles
RepoNameIndex = "metadata.labels." + fleet.RepoLabel
// ImageScanGitRepoIndex is the name of the index for the gitrepo name in imagescans
ImageScanGitRepoIndex = "spec.gitrepoName"
// BundleDownstreamResourceIndex is the name of the index for downstream resources (secrets and configmaps) in bundles
BundleDownstreamResourceIndex = "spec.downstreamResources"
// GitRepoClientSecretNameIndex is the name of the index for the client secret name in gitrepos
GitRepoClientSecretNameIndex = "spec.clientSecretName" //nolint:gosec // not a credential
// GitRepoHelmSecretNameIndex is the name of the index for the helm secret name in gitrepos
GitRepoHelmSecretNameIndex = "spec.helmSecretName"
// GitRepoHelmSecretNameForPathsIndex is the name of the index for the helm secret name for paths in gitrepos
GitRepoHelmSecretNameForPathsIndex = "spec.helmSecretNameForPaths"
)
var (
DefaultManagerImage = "rancher/fleet" + ":" + version.Version
DefaultAgentImage = "rancher/fleet-agent" + ":" + version.Version
DefaultGitClientTimeout = metav1.Duration{Duration: 30 * time.Second}
config *Config
callbacks = map[int]func(*Config) error{}
callbackID int
callbackLock sync.Mutex
)
// Config is the config for the fleet controller and agent. Each use slightly
// different fields from this struct. It is stored as JSON in configmaps under
// the 'config' key.
type Config struct {
// AgentImage defaults to rancher/fleet-agent:version if empty, can include a prefixed SystemDefaultRegistry
AgentImage string `json:"agentImage,omitempty"`
AgentImagePullPolicy string `json:"agentImagePullPolicy,omitempty"`
// SystemDefaultRegistry used by Rancher when constructing the
// agentImage string, it's in the config so fleet can remove it if a
// private repo url prefix is specified on the agent's cluster resource
SystemDefaultRegistry string `json:"systemDefaultRegistry,omitempty"`
// AgentCheckinInterval determines how often agents update their clusters status, defaults to 15m
AgentCheckinInterval metav1.Duration `json:"agentCheckinInterval,omitzero"`
// ManageAgent if present and set to false, no bundles will be created to manage agents
ManageAgent *bool `json:"manageAgent,omitempty"`
// Labels are copied to the cluster registration resource. In detail:
// fleet-controller will copy the labels to the fleet-agent's config,
// fleet-agent copies the labels to the cluster registration resource,
// when fleet-controller accepts the registration, the labels are
// copied to the cluster resource.
// +optional
Labels map[string]string `json:"labels,omitempty"`
// ClientID of the cluster to associate with. Used by the agent only.
// +optional
ClientID string `json:"clientID,omitempty"`
// APIServerURL is the URL of the fleet-controller's k8s API server. It
// can be empty, if the value is provided in the cluster's kubeconfig
// secret instead. The value is copied into the fleet-agent-bootstrap
// secret on the downstream cluster.
// +optional
APIServerURL string `json:"apiServerURL,omitempty"`
// APIServerCA is the CA bundle used to connect to the
// fleet-controllers k8s API server. It can be empty, if the value is
// provided in the cluster's kubeconfig secret instead. The value is
// copied into the fleet-agent-bootstrap secret on the downstream
// cluster.
// +optional
APIServerCA []byte `json:"apiServerCA,omitempty"`
Bootstrap Bootstrap `json:"bootstrap,omitzero"`
// IgnoreClusterRegistrationLabels if set to true, the labels on the cluster registration resource will not be copied to the cluster resource.
IgnoreClusterRegistrationLabels bool `json:"ignoreClusterRegistrationLabels,omitempty"`
// AgentTLSMode supports two values: `system-store` and `strict`. If set to `system-store`, instructs the agent
// to trust CA bundles from the operating system's store. If set to `strict`, then the agent shall only connect
// to a server which uses the exact CA configured when creating/updating the agent.
AgentTLSMode string `json:"agentTLSMode,omitempty"`
// The amount of time to wait for a response from the server before
// canceling the request. Used to retrieve the latest commit of configured
// git repositories. A non-existent value or 0 will result in a timeout of
// 30 seconds.
GitClientTimeout metav1.Duration `json:"gitClientTimeout,omitzero"`
// GarbageCollectionInterval determines how often agents clean up obsolete Helm releases.
GarbageCollectionInterval metav1.Duration `json:"garbageCollectionInterval,omitzero"`
// AgentWorkers specifies the maximum number of workers for each agent reconciler.
AgentWorkers AgentWorkers `json:"agentWorkers,omitzero"`
}
type AgentWorkers struct {
BundleDeployment string `json:"bundledeployment,omitempty"`
Drift string `json:"drift,omitempty"`
}
type Bootstrap struct {
Namespace string `json:"namespace,omitempty"`
AgentNamespace string `json:"agentNamespace,omitempty"`
ClusterLabels map[string]string `json:"clusterLabels,omitempty"`
// Repo to add at install time that will deploy to the local cluster. This allows
// one to fully bootstrap fleet, its configuration and all its downstream clusters
// in one shot.
Repo string `json:"repo,omitempty"`
// Secret is the gitrepo.ClientSecretName for agent from repo
Secret string `json:"secret,omitempty"`
Paths string `json:"paths,omitempty"`
Branch string `json:"branch,omitempty"`
}
// OnChange is used by agentmanagement to react to config changes. The callback is triggered by 'Set' via
// the config controller during startup and when the configmap changes.
func OnChange(ctx context.Context, f func(*Config) error) {
callbackLock.Lock()
defer callbackLock.Unlock()
callbackID++
id := callbackID
callbacks[id] = f
go func() {
<-ctx.Done()
callbackLock.Lock()
delete(callbacks, id)
callbackLock.Unlock()
}()
}
// Set doesn't trigger the callbacks, use SetAndTrigger for that. Set is used
// by controller-runtime controllers.
func Set(cfg *Config) {
config = cfg
}
// SetAndTrigger sets the config and triggers the callbacks. It is used by the
// agentmanagement wrangler controllers.
func SetAndTrigger(cfg *Config) error {
callbackLock.Lock()
defer callbackLock.Unlock()
config = cfg
for _, f := range callbacks {
if err := f(cfg); err != nil {
return err
}
}
return nil
}
func Get() *Config {
if config == nil {
panic("config.Get() called before Set()")
}
return config
}
func Exists(_ context.Context, namespace, name string, configMaps corev1.ConfigMapClient) (bool, error) {
_, err := configMaps.Get(namespace, name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
return false, nil
} else if err != nil {
return false, err
}
return true, nil
}
func Lookup(_ context.Context, namespace, name string, configMaps corev1.ConfigMapClient) (*Config, error) {
cm, err := configMaps.Get(namespace, name, metav1.GetOptions{})
if apierrors.IsNotFound(err) {
cm = &v1.ConfigMap{}
} else if err != nil {
return nil, err
}
return ReadConfig(cm)
}
func DefaultConfig() *Config {
return &Config{
AgentImage: DefaultAgentImage,
GitClientTimeout: DefaultGitClientTimeout,
}
}
func ReadConfig(cm *v1.ConfigMap) (*Config, error) {
cfg := DefaultConfig()
data := cm.Data[Key]
if len(data) == 0 {
return cfg, nil
}
err := yaml.Unmarshal([]byte(data), &cfg)
return cfg, err
}
func ToConfigMap(namespace, name string, cfg *Config) (*v1.ConfigMap, error) {
bytes, err := json.Marshal(cfg)
if err != nil {
return nil, err
}
return &v1.ConfigMap{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: namespace,
},
Data: map[string]string{
Key: string(bytes),
},
}, nil
}