Skip to content

Commit 3ca80b9

Browse files
committed
Merge remote-tracking branch 'origin/1.14.0' into k0s-1-28
2 parents 1e68265 + 595d3a2 commit 3ca80b9

File tree

7 files changed

+125
-112
lines changed

7 files changed

+125
-112
lines changed

.github/workflows/image-scan.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,13 @@ jobs:
3636
- name: Build and push local-artifact-mirror image
3737
id: local-artifact-mirror
3838
run: |
39-
make -C local-artifact-mirror apko build-ttl.sh
39+
make -C local-artifact-mirror build-ttl.sh
4040
echo "image=$(cat local-artifact-mirror/build/image)" >> $GITHUB_OUTPUT
4141
4242
- name: Build and push operator image
4343
id: operator
4444
run: |
45-
make -C operator apko build-ttl.sh build-chart-ttl.sh
45+
make -C operator build-ttl.sh build-chart-ttl.sh
4646
echo "image=$(cat operator/build/image)" >> $GITHUB_OUTPUT
4747
echo "chart=$(cat operator/build/chart)" >> $GITHUB_OUTPUT
4848

cmd/embedded-cluster/join.go

Lines changed: 48 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -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.
3738
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"`
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.
7167
func (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.
7773
func (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

342343
func 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

cmd/embedded-cluster/join_test.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010

1111
"github.com/k0sproject/dig"
1212
k0sconfig "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1"
13+
ecv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
1314
embeddedclusterv1beta1 "github.com/replicatedhq/embedded-cluster/kinds/apis/v1beta1"
1415
"github.com/stretchr/testify/assert"
1516
"github.com/stretchr/testify/require"
@@ -101,8 +102,14 @@ func TestJoinCommandResponseOverrides(t *testing.T) {
101102
t.Run(tname, func(t *testing.T) {
102103
req := require.New(t)
103104
join := JoinCommandResponse{
104-
K0sUnsupportedOverrides: tt.EmbeddedOverrides,
105-
EndUserK0sConfigOverrides: tt.EndUserOverrides,
105+
InstallationSpec: ecv1beta1.InstallationSpec{
106+
Config: &ecv1beta1.ConfigSpec{
107+
UnsupportedOverrides: ecv1beta1.UnsupportedOverrides{
108+
K0s: tt.EmbeddedOverrides,
109+
},
110+
},
111+
EndUserK0sConfigOverrides: tt.EndUserOverrides,
112+
},
106113
}
107114

108115
embedded, err := join.EmbeddedOverrides()

cmd/embedded-cluster/preflights.go

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77

88
"github.com/replicatedhq/embedded-cluster/pkg/defaults"
99
"github.com/replicatedhq/embedded-cluster/pkg/netutils"
10+
"github.com/replicatedhq/embedded-cluster/pkg/versions"
1011
"github.com/sirupsen/logrus"
1112
"github.com/urfave/cli/v2"
1213
)
@@ -126,13 +127,18 @@ var joinRunPreflightsCommand = &cli.Command{
126127
return fmt.Errorf("unable to get join token: %w", err)
127128
}
128129

129-
setProxyEnv(jcmd.Proxy)
130-
proxyOK, localIP, err := checkProxyConfigForLocalIP(jcmd.Proxy, networkInterface)
130+
// check to make sure the version returned by the join token is the same as the one we are running
131+
if jcmd.EmbeddedClusterVersion != versions.Version {
132+
return fmt.Errorf("embedded cluster version mismatch - this binary is version %q, but the cluster is running version %q", versions.Version, jcmd.EmbeddedClusterVersion)
133+
}
134+
135+
setProxyEnv(jcmd.InstallationSpec.Proxy)
136+
proxyOK, localIP, err := checkProxyConfigForLocalIP(jcmd.InstallationSpec.Proxy, networkInterface)
131137
if err != nil {
132138
return fmt.Errorf("failed to check proxy config for local IP: %w", err)
133139
}
134140
if !proxyOK {
135-
return fmt.Errorf("no-proxy config %q does not allow access to local IP %q", jcmd.Proxy.NoProxy, localIP)
141+
return fmt.Errorf("no-proxy config %q does not allow access to local IP %q", jcmd.InstallationSpec.Proxy.NoProxy, localIP)
136142
}
137143

138144
isAirgap := c.String("airgap-bundle") != ""
@@ -142,15 +148,15 @@ var joinRunPreflightsCommand = &cli.Command{
142148
return err
143149
}
144150

145-
applier, err := getAddonsApplier(c, "", jcmd.Proxy)
151+
applier, err := getAddonsApplier(c, "", jcmd.InstallationSpec.Proxy)
146152
if err != nil {
147153
return err
148154
}
149155

150156
logrus.Debugf("running host preflights")
151-
replicatedAPIURL := jcmd.MetricsBaseURL
157+
replicatedAPIURL := jcmd.InstallationSpec.MetricsBaseURL
152158
proxyRegistryURL := fmt.Sprintf("https://%s", defaults.ProxyRegistryAddress)
153-
if err := RunHostPreflights(c, applier, replicatedAPIURL, proxyRegistryURL, isAirgap, jcmd.Proxy); err != nil {
159+
if err := RunHostPreflights(c, applier, replicatedAPIURL, proxyRegistryURL, isAirgap, jcmd.InstallationSpec.Proxy); err != nil {
154160
err := fmt.Errorf("unable to run host preflights locally: %w", err)
155161
return err
156162
}

0 commit comments

Comments
 (0)