-
Notifications
You must be signed in to change notification settings - Fork 479
Expand file tree
/
Copy pathbootstrap.go
More file actions
270 lines (239 loc) · 10.1 KB
/
bootstrap.go
File metadata and controls
270 lines (239 loc) · 10.1 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
package operator
import (
"fmt"
"os"
"path/filepath"
"strings"
"k8s.io/klog/v2"
configv1 "github.com/openshift/api/config/v1"
ctrlcommon "github.com/openshift/machine-config-operator/pkg/controller/common"
templatectrl "github.com/openshift/machine-config-operator/pkg/controller/template"
)
type manifest struct {
name string
data []byte
filename string
}
// RenderBootstrap writes to destinationDir static Pods.
func RenderBootstrap(
dependenciesFiles BootstrapDependenciesFiles,
imgs *ctrlcommon.Images,
destinationDir, releaseImage string,
) error {
dependencies, err := NewBootstrapDependencies(dependenciesFiles)
if err != nil {
return fmt.Errorf("error parsing dependencies for MCO bootstrap: %w", err)
}
config, err := buildSpec(dependencies, imgs, releaseImage)
if err != nil {
return fmt.Errorf("error building spec for MCO bootstrap: %w", err)
}
manifests := []manifest{
{
name: "manifests/machineconfigcontroller/controllerconfig.yaml",
filename: "bootstrap/manifests/machineconfigcontroller-controllerconfig.yaml",
}, {
name: "manifests/master.machineconfigpool.yaml",
filename: "bootstrap/manifests/master.machineconfigpool.yaml",
}, {
name: "manifests/worker.machineconfigpool.yaml",
filename: "bootstrap/manifests/worker.machineconfigpool.yaml",
}, {
name: "manifests/bootstrap-pod-v2.yaml",
filename: "bootstrap/machineconfigoperator-bootstrap-pod.yaml",
}, {
data: []byte(dependencies.PullSecret),
filename: "bootstrap/manifests/machineconfigcontroller-pull-secret",
}, {
name: "manifests/machineconfigserver/csr-bootstrap-role-binding.yaml",
filename: "manifests/csr-bootstrap-role-binding.yaml",
}, {
name: "manifests/machineconfigserver/kube-apiserver-serving-ca-configmap.yaml",
filename: "manifests/kube-apiserver-serving-ca-configmap.yaml",
},
}
if dependencies.Infrastructure.Status.ControlPlaneTopology == configv1.HighlyAvailableArbiterMode {
manifests = append(manifests, manifest{
name: "manifests/arbiter.machineconfigpool.yaml",
filename: "bootstrap/manifests/arbiter.machineconfigpool.yaml",
})
}
manifests = appendManifestsByPlatform(manifests, dependencies.Infrastructure)
for _, m := range manifests {
var b []byte
var err error
switch {
case m.name != "":
klog.Info(m.name)
b, err = renderAsset(config, m.name)
if err != nil {
return err
}
case len(m.data) > 0:
b = m.data
default:
continue
}
path := filepath.Join(destinationDir, m.filename)
dirname := filepath.Dir(path)
if err := os.MkdirAll(dirname, 0o755); err != nil {
return err
}
// Disable gosec here to avoid throwing
// G306: Expect WriteFile permissions to be 0600 or less
// #nosec
if err := os.WriteFile(path, b, 0o644); err != nil {
return err
}
}
return nil
}
func buildSpec(dependencies *BootstrapDependencies, imgs *ctrlcommon.Images, releaseImage string) (*renderConfig, error) {
// create ControllerConfigSpec
spec, err := createDiscoveredControllerConfigSpec(
dependencies.Infrastructure,
dependencies.Network,
dependencies.Proxy,
dependencies.DNS)
if err != nil {
return nil, err
}
if dependencies.AdditionalTrustBundle != "" {
spec.AdditionalTrustBundle = []byte(dependencies.AdditionalTrustBundle)
}
if dependencies.CloudConfig != "" {
spec.CloudProviderConfig = dependencies.CloudConfig
}
// Append the kube-ca if given.
if dependencies.KubeAPIServerServingCA != "" {
spec.KubeAPIServerServingCAData = []byte(dependencies.KubeAPIServerServingCA)
}
// Set the cloud-provider CA if given.
if dependencies.CloudProviderCA != "" {
spec.CloudProviderCAData = []byte(dependencies.CloudProviderCA)
}
spec.RootCAData = []byte(dependencies.MCSCA)
spec.PullSecret = nil
spec.BaseOSContainerImage = imgs.BaseOSContainerImage
spec.BaseOSExtensionsContainerImage = imgs.BaseOSExtensionsContainerImage
spec.ReleaseImage = releaseImage
spec.Images = map[string]string{
templatectrl.MachineConfigOperatorKey: imgs.MachineConfigOperator,
templatectrl.APIServerWatcherKey: imgs.MachineConfigOperator,
templatectrl.InfraImageKey: imgs.InfraImage,
templatectrl.KeepalivedKey: imgs.Keepalived,
templatectrl.CorednsKey: imgs.Coredns,
templatectrl.HaproxyKey: imgs.Haproxy,
templatectrl.BaremetalRuntimeCfgKey: imgs.BaremetalRuntimeCfg,
templatectrl.KubeRbacProxyKey: imgs.KubeRbacProxy,
templatectrl.DockerRegistryKey: imgs.DockerRegistry,
}
config := getRenderConfig("", dependencies.KubeAPIServerServingCA, spec,
&imgs.RenderConfigImages, dependencies.Infrastructure, nil, nil, "2", "")
return config, nil
}
func appendManifestsByPlatform(manifests []manifest, infra *configv1.Infrastructure) []manifest {
lbType := configv1.LoadBalancerTypeOpenShiftManagedDefault
if infra.Status.PlatformStatus.BareMetal != nil {
if infra.Status.PlatformStatus.BareMetal.LoadBalancer != nil {
lbType = infra.Status.PlatformStatus.BareMetal.LoadBalancer.Type
}
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.BareMetalPlatformType)), lbType)
}
if infra.Status.PlatformStatus.OpenStack != nil {
if infra.Status.PlatformStatus.OpenStack.LoadBalancer != nil {
lbType = infra.Status.PlatformStatus.OpenStack.LoadBalancer.Type
}
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.OpenStackPlatformType)), lbType)
}
if infra.Status.PlatformStatus.Ovirt != nil {
if infra.Status.PlatformStatus.Ovirt.LoadBalancer != nil {
lbType = infra.Status.PlatformStatus.Ovirt.LoadBalancer.Type
}
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.OvirtPlatformType)), lbType)
}
if infra.Status.PlatformStatus.VSphere != nil {
// TODO(mko) It is not clear why for user-managed LB and for ELB we want to skip CoreDNS as every
// other platform deploys CoreDNS without keepalived, and only vSphere skips both.
// As this only refactors the existing code, I do not want to change this behaviour.
// vSphere allows setting user-managed LB by simply leaving the VIPs in PlatformStatus empty.
if len(infra.Status.PlatformStatus.VSphere.APIServerInternalIPs) == 0 {
return manifests
}
if infra.Status.PlatformStatus.VSphere.LoadBalancer != nil {
if infra.Status.PlatformStatus.VSphere.LoadBalancer.Type != configv1.LoadBalancerTypeOpenShiftManagedDefault {
return manifests
}
}
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.VSpherePlatformType)), lbType)
}
if infra.Status.PlatformStatus.Nutanix != nil {
if infra.Status.PlatformStatus.Nutanix.LoadBalancer != nil {
lbType = infra.Status.PlatformStatus.Nutanix.LoadBalancer.Type
}
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.NutanixPlatformType)), lbType)
}
if infra.Status.PlatformStatus.GCP != nil {
// Generate just the CoreDNS manifests for the GCP platform only when the DNSType is `ClusterHosted`.
if infra.Status.PlatformStatus.GCP.CloudLoadBalancerConfig != nil && infra.Status.PlatformStatus.GCP.CloudLoadBalancerConfig.DNSType == configv1.ClusterHostedDNSType {
// We do not need the keepalived manifests to be generated because the cloud default Load Balancers are in use.
// So, setting the lbType to `UserManaged` although the default cloud LBs are not user managed.
lbType = configv1.LoadBalancerTypeUserManaged
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.GCPPlatformType)), lbType)
}
}
if infra.Status.PlatformStatus.AWS != nil {
// Generate just the CoreDNS manifests for the AWS platform only when the DNSType is `ClusterHosted`.
if infra.Status.PlatformStatus.AWS.CloudLoadBalancerConfig != nil && infra.Status.PlatformStatus.AWS.CloudLoadBalancerConfig.DNSType == configv1.ClusterHostedDNSType {
// We do not need the keepalived manifests to be generated because the cloud default Load Balancers are in use.
// So, setting the lbType to `UserManaged` although the default cloud LBs are not user managed.
lbType = configv1.LoadBalancerTypeUserManaged
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.AWSPlatformType)), lbType)
}
}
if infra.Status.PlatformStatus.Azure != nil {
// Generate just the CoreDNS manifests for the Azure platform only when the DNSType is `ClusterHosted`.
if infra.Status.PlatformStatus.Azure.CloudLoadBalancerConfig != nil && infra.Status.PlatformStatus.Azure.CloudLoadBalancerConfig.DNSType == configv1.ClusterHostedDNSType {
// We do not need the keepalived manifests to be generated because the cloud default Load Balancers are in use.
// So, setting the lbType to `UserManaged` although the default cloud LBs are not user managed.
lbType = configv1.LoadBalancerTypeUserManaged
manifests = getPlatformManifests(manifests, strings.ToLower(string(configv1.AzurePlatformType)), lbType)
}
}
return manifests
}
func getPlatformManifests(manifests []manifest, platformName string, lbType configv1.PlatformLoadBalancerType) []manifest {
var corednsName string
var corefileName string
switch platformName {
case strings.ToLower(string(configv1.GCPPlatformType)), strings.ToLower(string(configv1.AWSPlatformType)), strings.ToLower(string(configv1.AzurePlatformType)):
corednsName = "manifests/cloud-platform-alt-dns/coredns.yaml"
corefileName = "manifests/cloud-platform-alt-dns/coredns-corefile.tmpl"
default:
corednsName = "manifests/on-prem/coredns.yaml"
corefileName = "manifests/on-prem/coredns-corefile.tmpl"
}
platformManifests := append([]manifest{},
manifest{
name: corednsName,
filename: platformName + "/manifests/coredns.yaml",
},
manifest{
name: corefileName,
filename: platformName + "/static-pod-resources/coredns/Corefile.tmpl",
},
)
if lbType == configv1.LoadBalancerTypeOpenShiftManagedDefault || lbType == "" {
platformManifests = append(platformManifests,
manifest{
name: "manifests/on-prem/keepalived.yaml",
filename: platformName + "/manifests/keepalived.yaml",
},
manifest{
name: "manifests/on-prem/keepalived.conf.tmpl",
filename: platformName + "/static-pod-resources/keepalived/keepalived.conf.tmpl",
},
)
}
return append(manifests, platformManifests...)
}