@@ -31,21 +31,17 @@ import (
3131 "github.com/replicatedhq/embedded-cluster/pkg/netutils"
3232 "github.com/replicatedhq/embedded-cluster/pkg/prompts"
3333 "github.com/replicatedhq/embedded-cluster/pkg/spinner"
34+ "github.com/replicatedhq/embedded-cluster/pkg/versions"
3435)
3536
3637// JoinCommandResponse is the response from the kots api we use to fetch the k0s join token.
3738type 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"`
4945}
5046
5147// extractK0sConfigOverridePatch parses the provided override and returns a dig.Mapping that
@@ -69,13 +65,13 @@ func (j JoinCommandResponse) extractK0sConfigOverridePatch(data []byte) (dig.Map
6965// EndUserOverrides returns a dig.Mapping that can be applied on top of a k0s configuration.
7066// This patch is assembled based on the EndUserK0sConfigOverrides field.
7167func (j JoinCommandResponse ) EndUserOverrides () (dig.Mapping , error ) {
72- return j .extractK0sConfigOverridePatch ([]byte (j .EndUserK0sConfigOverrides ))
68+ return j .extractK0sConfigOverridePatch ([]byte (j .InstallationSpec . EndUserK0sConfigOverrides ))
7369}
7470
7571// EmbeddedOverrides returns a dig.Mapping that can be applied on top of a k0s configuration.
7672// This patch is assembled based on the K0sUnsupportedOverrides field.
7773func (j JoinCommandResponse ) EmbeddedOverrides () (dig.Mapping , error ) {
78- return j .extractK0sConfigOverridePatch ([]byte (j .K0sUnsupportedOverrides ))
74+ return j .extractK0sConfigOverridePatch ([]byte (j .InstallationSpec . Config . UnsupportedOverrides . K0s ))
7975}
8076
8177// 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 {
114110 logrus .Debugf ("starting %s service" , binName )
115111 if err := startK0sService (); err != nil {
116112 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 )
118114 return err
119115 }
120116
121117 loading .Infof ("Waiting for %s node to be ready" , binName )
122118 logrus .Debugf ("waiting for k0s to be ready" )
123119 if err := waitForK0s (); err != nil {
124120 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 )
126122 return err
127123 }
128124
@@ -198,13 +194,18 @@ var joinCommand = &cli.Command{
198194 return fmt .Errorf ("unable to get join token: %w" , err )
199195 }
200196
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 )
203204 if err != nil {
204205 return fmt .Errorf ("failed to check proxy config for local IP: %w" , err )
205206 }
206207 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 )
208209 }
209210
210211 isAirgap := c .String ("airgap-bundle" ) != ""
@@ -216,25 +217,25 @@ var joinCommand = &cli.Command{
216217 }
217218 }
218219
219- metrics .ReportJoinStarted (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID )
220+ metrics .ReportJoinStarted (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID )
220221 logrus .Debugf ("materializing %s binaries" , binName )
221222 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 )
223224 return err
224225 }
225226
226- applier , err := getAddonsApplier (c , "" , jcmd .Proxy )
227+ applier , err := getAddonsApplier (c , "" , jcmd .InstallationSpec . Proxy )
227228 if err != nil {
228- metrics .ReportJoinFailed (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID , err )
229+ metrics .ReportJoinFailed (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID , err )
229230 return err
230231 }
231232
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
234235 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 {
236237 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 )
238239 return err
239240 }
240241
@@ -246,54 +247,54 @@ var joinCommand = &cli.Command{
246247 logrus .Debugf ("saving token to disk" )
247248 if err := saveTokenToDisk (jcmd .K0sToken ); err != nil {
248249 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 )
250251 return err
251252 }
252253
253254 logrus .Debugf ("installing %s binaries" , binName )
254255 if err := installK0sBinary (); err != nil {
255256 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 )
257258 return err
258259 }
259260
260261 if jcmd .AirgapRegistryAddress != "" {
261262 if err := airgap .AddInsecureRegistry (jcmd .AirgapRegistryAddress ); err != nil {
262263 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 )
264265 return err
265266 }
266267 }
267268
268269 logrus .Debugf ("creating systemd unit files" )
269270 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
272273 }
273274 // 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 {
275276 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 )
277278 return err
278279 }
279280
280281 logrus .Debugf ("overriding network configuration" )
281282 if err := applyNetworkConfiguration (jcmd , networkInterface ); err != nil {
282283 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 )
284285 }
285286
286287 logrus .Debugf ("applying configuration overrides" )
287288 if err := applyJoinConfigurationOverrides (jcmd ); err != nil {
288289 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 )
290291 return err
291292 }
292293
293294 logrus .Debugf ("joining node to cluster" )
294295 if err := runK0sInstallCommand (jcmd .K0sJoinCommand , networkInterface ); err != nil {
295296 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 )
297298 return err
298299 }
299300
@@ -302,45 +303,45 @@ var joinCommand = &cli.Command{
302303 }
303304
304305 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 )
306307 logrus .Debugf ("worker node join finished" )
307308 return nil
308309 }
309310
310311 kcli , err := kubeutils .KubeClient ()
311312 if err != nil {
312313 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 )
314315 return err
315316 }
316317 hostname , err := os .Hostname ()
317318 if err != nil {
318319 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 )
320321 return err
321322 }
322323 if err := waitForNode (c .Context , kcli , hostname ); err != nil {
323324 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 )
325326 return err
326327 }
327328
328329 if c .Bool ("enable-ha" ) {
329330 if err := maybeEnableHA (c .Context , kcli ); err != nil {
330331 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 )
332333 return err
333334 }
334335 }
335336
336- metrics .ReportJoinSucceeded (c .Context , jcmd .MetricsBaseURL , jcmd .ClusterID )
337+ metrics .ReportJoinSucceeded (c .Context , jcmd .InstallationSpec . MetricsBaseURL , jcmd .ClusterID )
337338 logrus .Debugf ("controller node join finished" )
338339 return nil
339340 },
340341}
341342
342343func applyNetworkConfiguration (jcmd * JoinCommandResponse , networkInterface string ) error {
343- if jcmd .Network != nil {
344+ if jcmd .InstallationSpec . Network != nil {
344345 clusterSpec := config .RenderK0sConfig ()
345346 address , err := netutils .FirstValidAddress (networkInterface )
346347 if err != nil {
@@ -350,13 +351,13 @@ func applyNetworkConfiguration(jcmd *JoinCommandResponse, networkInterface strin
350351 clusterSpec .Spec .Storage .Etcd .PeerAddress = address
351352 // NOTE: we should be copying everything from the in cluster config spec and overriding
352353 // 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 != "" {
356357 if clusterSpec .Spec .API .ExtraArgs == nil {
357358 clusterSpec .Spec .API .ExtraArgs = map [string ]string {}
358359 }
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
360361 }
361362 clusterSpecYaml , err := k8syaml .Marshal (clusterSpec )
362363
0 commit comments