@@ -31,21 +31,17 @@ import (
31
31
"github.com/replicatedhq/embedded-cluster/pkg/netutils"
32
32
"github.com/replicatedhq/embedded-cluster/pkg/prompts"
33
33
"github.com/replicatedhq/embedded-cluster/pkg/spinner"
34
+ "github.com/replicatedhq/embedded-cluster/pkg/versions"
34
35
)
35
36
36
37
// JoinCommandResponse is the response from the kots api we use to fetch the k0s join token.
37
38
type JoinCommandResponse struct {
38
- K0sJoinCommand string `json:"k0sJoinCommand"`
39
- K0sToken string `json:"k0sToken"`
40
- ClusterID uuid.UUID `json:"clusterID"`
41
- K0sUnsupportedOverrides string `json:"k0sUnsupportedOverrides"`
42
- EndUserK0sConfigOverrides string `json:"endUserK0sConfigOverrides"`
43
- // MetricsBaseURL is the https://replicated.app endpoint url
44
- MetricsBaseURL string `json:"metricsBaseURL"`
45
- AirgapRegistryAddress string `json:"airgapRegistryAddress"`
46
- Proxy * ecv1beta1.ProxySpec `json:"proxy"`
47
- Network * ecv1beta1.NetworkSpec `json:"network"`
48
- LocalArtifactMirrorPort int `json:"localArtifactMirrorPort,omitempty"`
39
+ K0sJoinCommand string `json:"k0sJoinCommand"`
40
+ K0sToken string `json:"k0sToken"`
41
+ ClusterID uuid.UUID `json:"clusterID"`
42
+ EmbeddedClusterVersion string `json:"embeddedClusterVersion"`
43
+ AirgapRegistryAddress string `json:"airgapRegistryAddress"`
44
+ InstallationSpec ecv1beta1.InstallationSpec `json:"installationSpec,omitempty"`
49
45
}
50
46
51
47
// extractK0sConfigOverridePatch parses the provided override and returns a dig.Mapping that
@@ -69,13 +65,13 @@ func (j JoinCommandResponse) extractK0sConfigOverridePatch(data []byte) (dig.Map
69
65
// EndUserOverrides returns a dig.Mapping that can be applied on top of a k0s configuration.
70
66
// This patch is assembled based on the EndUserK0sConfigOverrides field.
71
67
func (j JoinCommandResponse ) EndUserOverrides () (dig.Mapping , error ) {
72
- return j .extractK0sConfigOverridePatch ([]byte (j .EndUserK0sConfigOverrides ))
68
+ return j .extractK0sConfigOverridePatch ([]byte (j .InstallationSpec . EndUserK0sConfigOverrides ))
73
69
}
74
70
75
71
// EmbeddedOverrides returns a dig.Mapping that can be applied on top of a k0s configuration.
76
72
// This patch is assembled based on the K0sUnsupportedOverrides field.
77
73
func (j JoinCommandResponse ) EmbeddedOverrides () (dig.Mapping , error ) {
78
- return j .extractK0sConfigOverridePatch ([]byte (j .K0sUnsupportedOverrides ))
74
+ return j .extractK0sConfigOverridePatch ([]byte (j .InstallationSpec . Config . UnsupportedOverrides . K0s ))
79
75
}
80
76
81
77
// getJoinToken issues a request to the kots api to get the actual join command
@@ -114,15 +110,15 @@ func startAndWaitForK0s(c *cli.Context, jcmd *JoinCommandResponse) error {
114
110
logrus .Debugf ("starting %s service" , binName )
115
111
if err := startK0sService (); err != nil {
116
112
err := fmt .Errorf ("unable to start service: %w" , err )
117
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
113
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
118
114
return err
119
115
}
120
116
121
117
loading .Infof ("Waiting for %s node to be ready" , binName )
122
118
logrus .Debugf ("waiting for k0s to be ready" )
123
119
if err := waitForK0s (); err != nil {
124
120
err := fmt .Errorf ("unable to wait for node: %w" , err )
125
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
121
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
126
122
return err
127
123
}
128
124
@@ -198,13 +194,18 @@ var joinCommand = &cli.Command{
198
194
return fmt .Errorf ("unable to get join token: %w" , err )
199
195
}
200
196
201
- setProxyEnv (jcmd .Proxy )
202
- proxyOK , localIP , err := checkProxyConfigForLocalIP (jcmd .Proxy , networkInterface )
197
+ // check to make sure the version returned by the join token is the same as the one we are running
198
+ if jcmd .EmbeddedClusterVersion != versions .Version {
199
+ return fmt .Errorf ("embedded cluster version mismatch - this binary is version %q, but the cluster is running version %q" , versions .Version , jcmd .EmbeddedClusterVersion )
200
+ }
201
+
202
+ setProxyEnv (jcmd .InstallationSpec .Proxy )
203
+ proxyOK , localIP , err := checkProxyConfigForLocalIP (jcmd .InstallationSpec .Proxy , networkInterface )
203
204
if err != nil {
204
205
return fmt .Errorf ("failed to check proxy config for local IP: %w" , err )
205
206
}
206
207
if ! proxyOK {
207
- return fmt .Errorf ("no-proxy config %q does not allow access to local IP %q" , jcmd .Proxy .NoProxy , localIP )
208
+ return fmt .Errorf ("no-proxy config %q does not allow access to local IP %q" , jcmd .InstallationSpec . Proxy .NoProxy , localIP )
208
209
}
209
210
210
211
isAirgap := c .String ("airgap-bundle" ) != ""
@@ -216,25 +217,25 @@ var joinCommand = &cli.Command{
216
217
}
217
218
}
218
219
219
- metrics .ReportJoinStarted (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID )
220
+ metrics .ReportJoinStarted (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID )
220
221
logrus .Debugf ("materializing %s binaries" , binName )
221
222
if err := materializeFiles (c ); err != nil {
222
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
223
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
223
224
return err
224
225
}
225
226
226
- applier , err := getAddonsApplier (c , "" , jcmd .Proxy )
227
+ applier , err := getAddonsApplier (c , "" , jcmd .InstallationSpec . Proxy )
227
228
if err != nil {
228
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
229
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
229
230
return err
230
231
}
231
232
232
- // jcmd.MetricsBaseURL is the replicated.app endpoint url
233
- replicatedAPIURL := jcmd .MetricsBaseURL
233
+ // jcmd.InstallationSpec. MetricsBaseURL is the replicated.app endpoint url
234
+ replicatedAPIURL := jcmd .InstallationSpec . MetricsBaseURL
234
235
proxyRegistryURL := fmt .Sprintf ("https://%s" , defaults .ProxyRegistryAddress )
235
- if err := RunHostPreflights (c , applier , replicatedAPIURL , proxyRegistryURL , isAirgap , jcmd .Proxy ); err != nil {
236
+ if err := RunHostPreflights (c , applier , replicatedAPIURL , proxyRegistryURL , isAirgap , jcmd .InstallationSpec . Proxy ); err != nil {
236
237
err := fmt .Errorf ("unable to run host preflights locally: %w" , err )
237
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
238
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
238
239
return err
239
240
}
240
241
@@ -246,54 +247,54 @@ var joinCommand = &cli.Command{
246
247
logrus .Debugf ("saving token to disk" )
247
248
if err := saveTokenToDisk (jcmd .K0sToken ); err != nil {
248
249
err := fmt .Errorf ("unable to save token to disk: %w" , err )
249
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
250
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
250
251
return err
251
252
}
252
253
253
254
logrus .Debugf ("installing %s binaries" , binName )
254
255
if err := installK0sBinary (); err != nil {
255
256
err := fmt .Errorf ("unable to install k0s binary: %w" , err )
256
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
257
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
257
258
return err
258
259
}
259
260
260
261
if jcmd .AirgapRegistryAddress != "" {
261
262
if err := airgap .AddInsecureRegistry (jcmd .AirgapRegistryAddress ); err != nil {
262
263
err := fmt .Errorf ("unable to add insecure registry: %w" , err )
263
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
264
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
264
265
return err
265
266
}
266
267
}
267
268
268
269
logrus .Debugf ("creating systemd unit files" )
269
270
localArtifactMirrorPort := defaults .LocalArtifactMirrorPort
270
- if jcmd .LocalArtifactMirrorPort > 0 {
271
- localArtifactMirrorPort = jcmd .LocalArtifactMirrorPort
271
+ if jcmd .InstallationSpec . LocalArtifactMirror != nil && jcmd . InstallationSpec . LocalArtifactMirror . Port > 0 {
272
+ localArtifactMirrorPort = jcmd .InstallationSpec . LocalArtifactMirror . Port
272
273
}
273
274
// both controller and worker nodes will have 'worker' in the join command
274
- if err := createSystemdUnitFiles (! strings .Contains (jcmd .K0sJoinCommand , "controller" ), jcmd .Proxy , localArtifactMirrorPort ); err != nil {
275
+ if err := createSystemdUnitFiles (! strings .Contains (jcmd .K0sJoinCommand , "controller" ), jcmd .InstallationSpec . Proxy , localArtifactMirrorPort ); err != nil {
275
276
err := fmt .Errorf ("unable to create systemd unit files: %w" , err )
276
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
277
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
277
278
return err
278
279
}
279
280
280
281
logrus .Debugf ("overriding network configuration" )
281
282
if err := applyNetworkConfiguration (jcmd , networkInterface ); err != nil {
282
283
err := fmt .Errorf ("unable to apply network configuration: %w" , err )
283
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
284
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
284
285
}
285
286
286
287
logrus .Debugf ("applying configuration overrides" )
287
288
if err := applyJoinConfigurationOverrides (jcmd ); err != nil {
288
289
err := fmt .Errorf ("unable to apply configuration overrides: %w" , err )
289
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
290
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
290
291
return err
291
292
}
292
293
293
294
logrus .Debugf ("joining node to cluster" )
294
295
if err := runK0sInstallCommand (jcmd .K0sJoinCommand , networkInterface ); err != nil {
295
296
err := fmt .Errorf ("unable to join node to cluster: %w" , err )
296
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
297
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
297
298
return err
298
299
}
299
300
@@ -302,45 +303,45 @@ var joinCommand = &cli.Command{
302
303
}
303
304
304
305
if ! strings .Contains (jcmd .K0sJoinCommand , "controller" ) {
305
- metrics .ReportJoinSucceeded (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID )
306
+ metrics .ReportJoinSucceeded (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID )
306
307
logrus .Debugf ("worker node join finished" )
307
308
return nil
308
309
}
309
310
310
311
kcli , err := kubeutils .KubeClient ()
311
312
if err != nil {
312
313
err := fmt .Errorf ("unable to get kube client: %w" , err )
313
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
314
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
314
315
return err
315
316
}
316
317
hostname , err := os .Hostname ()
317
318
if err != nil {
318
319
err := fmt .Errorf ("unable to get hostname: %w" , err )
319
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
320
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
320
321
return err
321
322
}
322
323
if err := waitForNode (c .Context , kcli , hostname ); err != nil {
323
324
err := fmt .Errorf ("unable to wait for node: %w" , err )
324
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
325
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
325
326
return err
326
327
}
327
328
328
329
if c .Bool ("enable-ha" ) {
329
330
if err := maybeEnableHA (c .Context , kcli ); err != nil {
330
331
err := fmt .Errorf ("unable to enable high availability: %w" , err )
331
- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
332
+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
332
333
return err
333
334
}
334
335
}
335
336
336
- metrics .ReportJoinSucceeded (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID )
337
+ metrics .ReportJoinSucceeded (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID )
337
338
logrus .Debugf ("controller node join finished" )
338
339
return nil
339
340
},
340
341
}
341
342
342
343
func applyNetworkConfiguration (jcmd * JoinCommandResponse , networkInterface string ) error {
343
- if jcmd .Network != nil {
344
+ if jcmd .InstallationSpec . Network != nil {
344
345
clusterSpec := config .RenderK0sConfig ()
345
346
address , err := netutils .FirstValidAddress (networkInterface )
346
347
if err != nil {
@@ -350,13 +351,13 @@ func applyNetworkConfiguration(jcmd *JoinCommandResponse, networkInterface strin
350
351
clusterSpec .Spec .Storage .Etcd .PeerAddress = address
351
352
// NOTE: we should be copying everything from the in cluster config spec and overriding
352
353
// the node specific config from clusterSpec.GetClusterWideConfig()
353
- clusterSpec .Spec .Network .PodCIDR = jcmd .Network .PodCIDR
354
- clusterSpec .Spec .Network .ServiceCIDR = jcmd .Network .ServiceCIDR
355
- if jcmd .Network .NodePortRange != "" {
354
+ clusterSpec .Spec .Network .PodCIDR = jcmd .InstallationSpec . Network .PodCIDR
355
+ clusterSpec .Spec .Network .ServiceCIDR = jcmd .InstallationSpec . Network .ServiceCIDR
356
+ if jcmd .InstallationSpec . Network .NodePortRange != "" {
356
357
if clusterSpec .Spec .API .ExtraArgs == nil {
357
358
clusterSpec .Spec .API .ExtraArgs = map [string ]string {}
358
359
}
359
- clusterSpec .Spec .API .ExtraArgs ["service-node-port-range" ] = jcmd .Network .NodePortRange
360
+ clusterSpec .Spec .API .ExtraArgs ["service-node-port-range" ] = jcmd .InstallationSpec . Network .NodePortRange
360
361
}
361
362
clusterSpecYaml , err := k8syaml .Marshal (clusterSpec )
362
363
0 commit comments