Skip to content

Commit d803269

Browse files
[CLI]:Add TCP connection check (#584)
* Add websocket connection * Rename websocket to TCP * Refactor * Refactor * Up version * Refactor * Change store type * Change tcp connection tester name * Change tcp connection tester name * Up version * Fix
1 parent 3c2e87f commit d803269

File tree

6 files changed

+100
-21
lines changed

6 files changed

+100
-21
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
VERSION=v0.0.529
1+
VERSION=v0.0.530
22

33
OUT_DIR=dist
44
YEAR?=$(shell date +"%Y")

cmd/commands/runtime_install.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1141,7 +1141,13 @@ func preInstallationChecks(ctx context.Context, opts *RuntimeInstallOptions) err
11411141
}
11421142

11431143
if !opts.SkipClusterChecks {
1144-
err = kubeutil.EnsureClusterRequirements(ctx, opts.KubeFactory, opts.RuntimeName, cfConfig.GetCurrentContext().URL)
1144+
err = kubeutil.EnsureClusterRequirements(ctx, kubeutil.RuntimeInstallOptions{
1145+
KubeFactory: opts.KubeFactory,
1146+
Namespace: opts.RuntimeName,
1147+
ContextUrl: cfConfig.GetCurrentContext().URL,
1148+
AccessMode: opts.AccessMode,
1149+
TunnelRegisterHost: opts.TunnelRegisterHost,
1150+
})
11451151
}
11461152
handleCliStep(reporter.InstallStepRunPreCheckValidateClusterRequirements, "Ensuring cluster requirements", err, true, false)
11471153
if err != nil {

docs/releases/release_notes.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ cf version
2323

2424
```bash
2525
# download and extract the binary
26-
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.529/cf-linux-amd64.tar.gz | tar zx
26+
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.530/cf-linux-amd64.tar.gz | tar zx
2727

2828
# move the binary to your $PATH
2929
mv ./cf-linux-amd64 /usr/local/bin/cf
@@ -36,7 +36,7 @@ cf version
3636

3737
```bash
3838
# download and extract the binary
39-
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.529/cf-darwin-amd64.tar.gz | tar zx
39+
curl -L --output - https://github.com/codefresh-io/cli-v2/releases/download/v0.0.530/cf-darwin-amd64.tar.gz | tar zx
4040

4141
# move the binary to your $PATH
4242
mv ./cf-darwin-amd64 /usr/local/bin/cf

manifests/runtime.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
namespace: "{{ namespace }}"
66
spec:
77
defVersion: 2.0.0
8-
version: 0.0.529
8+
version: 0.0.530
99
bootstrapSpecifier: github.com/codefresh-io/cli-v2/manifests/argo-cd
1010
components:
1111
- name: events

pkg/store/store.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,8 @@ type Store struct {
134134
NetworkTesterName string
135135
NetworkTesterGenerateName string
136136
NetworkTesterImage string
137+
TCPConnectionTesterGenerateName string
138+
TCPConnectionTesterName string
137139
MinKubeVersion string
138140
MaxKubeVersion string
139141
MasterIngressName string
@@ -236,6 +238,8 @@ func init() {
236238
s.NetworkTesterName = "cf-network-tester"
237239
s.NetworkTesterGenerateName = "cf-network-tester-"
238240
s.NetworkTesterImage = "quay.io/codefresh/cf-venona-network-tester:latest"
241+
s.TCPConnectionTesterGenerateName = "cf-tcp-connections-tester-"
242+
s.TCPConnectionTesterName = "cf-tcp-connections-tester"
239243
s.MinKubeVersion = "v1.18.0"
240244
s.MaxKubeVersion = "v1.25.0"
241245
s.MasterIngressName = "-master"

pkg/util/kube/kube.go

Lines changed: 85 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"github.com/codefresh-io/cli-v2/pkg/store"
2727

2828
"github.com/argoproj-labs/argocd-autopilot/pkg/kube"
29+
platmodel "github.com/codefresh-io/go-sdk/pkg/codefresh/model"
2930
authv1 "k8s.io/api/authorization/v1"
3031
batchv1 "k8s.io/api/batch/v1"
3132
v1 "k8s.io/api/core/v1"
@@ -37,6 +38,14 @@ import (
3738
)
3839

3940
type (
41+
RuntimeInstallOptions struct {
42+
KubeFactory kube.Factory
43+
Namespace string
44+
ContextUrl string
45+
AccessMode platmodel.AccessMode
46+
TunnelRegisterHost string
47+
}
48+
4049
rbacValidation struct {
4150
Namespace string
4251
Resource string
@@ -53,16 +62,19 @@ type (
5362
LaunchJobOptions struct {
5463
Client kubernetes.Interface
5564
Namespace string
56-
JobName *string
57-
Image *string
65+
ContainerName string
66+
GenerateName string
67+
Image string
5868
Env []v1.EnvVar
5969
RestartPolicy v1.RestartPolicy
6070
BackOffLimit int32
6171
}
6272
)
6373

64-
func EnsureClusterRequirements(ctx context.Context, kubeFactory kube.Factory, namespace string, contextUrl string) error {
74+
func EnsureClusterRequirements(ctx context.Context, runtimeInstallOptions RuntimeInstallOptions) error {
6575
requirementsValidationErrorMessage := "cluster does not meet minimum requirements"
76+
namespace := runtimeInstallOptions.Namespace
77+
kubeFactory := runtimeInstallOptions.KubeFactory
6678
var specificErrorMessages []string
6779

6880
client, err := kubeFactory.KubernetesClientSet()
@@ -173,16 +185,67 @@ func EnsureClusterRequirements(ctx context.Context, kubeFactory kube.Factory, na
173185
return fmt.Errorf("%s: %v", requirementsValidationErrorMessage, specificErrorMessages)
174186
}
175187

176-
err = runNetworkTest(ctx, kubeFactory, contextUrl)
188+
err = runNetworkTest(ctx, kubeFactory, runtimeInstallOptions.ContextUrl)
177189
if err != nil {
178190
return fmt.Errorf("cluster network tests failed: %w ", err)
179191
}
180192

181193
log.G(ctx).Info("Network test finished successfully")
182194

195+
if runtimeInstallOptions.AccessMode == platmodel.AccessModeTunnel {
196+
err = runTCPConnectionTest(ctx, &runtimeInstallOptions)
197+
if err != nil {
198+
return fmt.Errorf("cluster TCP connection tests failed: %w ", err)
199+
}
200+
201+
log.G(ctx).Info("TCP connection test finished successfully")
202+
}
183203
return nil
184204
}
185205

206+
func runTCPConnectionTest(ctx context.Context, runtimeInstallOptions *RuntimeInstallOptions) error {
207+
const tcpConnectionTestsTimeout = 120 * time.Second
208+
envVars := map[string]string{
209+
"TUNNEL_REGISTER_HOST": runtimeInstallOptions.TunnelRegisterHost,
210+
}
211+
env := prepareEnvVars(envVars)
212+
213+
client, err := runtimeInstallOptions.KubeFactory.KubernetesClientSet()
214+
if err != nil {
215+
return fmt.Errorf("failed to create kubernetes client: %w", err)
216+
}
217+
218+
job, err := launchJob(ctx, client, LaunchJobOptions{
219+
Namespace: store.Get().DefaultNamespace,
220+
ContainerName: store.Get().TCPConnectionTesterName,
221+
GenerateName: store.Get().TCPConnectionTesterGenerateName,
222+
Image: store.Get().NetworkTesterImage,
223+
Env: env,
224+
RestartPolicy: v1.RestartPolicyNever,
225+
BackOffLimit: 0,
226+
})
227+
if err != nil {
228+
return err
229+
}
230+
231+
defer func() {
232+
err := deleteJob(ctx, client, job)
233+
if err != nil {
234+
log.G(ctx).Errorf("fail to delete tester pod: %s", err.Error())
235+
}
236+
}()
237+
238+
log.G(ctx).Info("Running TCP connection test...")
239+
ticker := time.NewTicker(5 * time.Second)
240+
defer ticker.Stop()
241+
timeoutChan := time.After(tcpConnectionTestsTimeout)
242+
podLastState, err := handleJobPodStates(ctx, client, job, ticker, timeoutChan)
243+
if err != nil {
244+
return err
245+
}
246+
return checkPodLastState(ctx, client, podLastState)
247+
}
248+
186249
func GetClusterSecret(ctx context.Context, kubeFactory kube.Factory, namespace string, name string) (*v1.Secret, error) {
187250
client, err := kubeFactory.KubernetesClientSet()
188251
if err != nil {
@@ -295,8 +358,9 @@ func runNetworkTest(ctx context.Context, kubeFactory kube.Factory, urls ...strin
295358

296359
job, err := launchJob(ctx, client, LaunchJobOptions{
297360
Namespace: store.Get().DefaultNamespace,
298-
JobName: &store.Get().NetworkTesterName,
299-
Image: &store.Get().NetworkTesterImage,
361+
ContainerName: store.Get().NetworkTesterName,
362+
GenerateName: store.Get().NetworkTesterGenerateName,
363+
Image: store.Get().NetworkTesterImage,
300364
Env: env,
301365
RestartPolicy: v1.RestartPolicyNever,
302366
BackOffLimit: 0,
@@ -315,17 +379,24 @@ func runNetworkTest(ctx context.Context, kubeFactory kube.Factory, urls ...strin
315379
log.G(ctx).Info("Running network test...")
316380
ticker := time.NewTicker(5 * time.Second)
317381
defer ticker.Stop()
318-
var podLastState *v1.Pod
319382
timeoutChan := time.After(networkTestsTimeout)
383+
podLastState, err := handleJobPodStates(ctx, client, job, ticker, timeoutChan)
384+
if err != nil {
385+
return err
386+
}
387+
return checkPodLastState(ctx, client, podLastState)
388+
}
320389

390+
func handleJobPodStates(ctx context.Context, client kubernetes.Interface, job *batchv1.Job, ticker *time.Ticker, timeoutChan <-chan time.Time) (*v1.Pod, error) {
391+
var podLastState *v1.Pod
321392
Loop:
322393
for {
323394
select {
324395
case <-ticker.C:
325396
log.G(ctx).Debug("Waiting for network tester to finish")
326397
currentPod, err := getPodByJob(ctx, client, job)
327398
if err != nil {
328-
return err
399+
return nil, err
329400
}
330401

331402
if currentPod == nil {
@@ -353,11 +424,10 @@ Loop:
353424
break Loop
354425
}
355426
case <-timeoutChan:
356-
return fmt.Errorf("network test timeout reached!")
427+
return nil, fmt.Errorf("network test timeout reached!")
357428
}
358429
}
359-
360-
return checkPodLastState(ctx, client, podLastState)
430+
return podLastState, nil
361431
}
362432

363433
func prepareEnvVars(vars map[string]string) []v1.EnvVar {
@@ -368,7 +438,6 @@ func prepareEnvVars(vars map[string]string) []v1.EnvVar {
368438
Value: value,
369439
})
370440
}
371-
372441
return env
373442
}
374443

@@ -449,16 +518,16 @@ func testNode(n v1.Node, req validationRequest) []string {
449518
func launchJob(ctx context.Context, client kubernetes.Interface, opts LaunchJobOptions) (*batchv1.Job, error) {
450519
jobSpec := &batchv1.Job{
451520
ObjectMeta: metav1.ObjectMeta{
452-
Name: *opts.JobName,
453-
Namespace: opts.Namespace,
521+
GenerateName: opts.GenerateName,
522+
Namespace: opts.Namespace,
454523
},
455524
Spec: batchv1.JobSpec{
456525
Template: v1.PodTemplateSpec{
457526
Spec: v1.PodSpec{
458527
Containers: []v1.Container{
459528
{
460-
Name: *opts.JobName,
461-
Image: *opts.Image,
529+
Name: opts.ContainerName,
530+
Image: opts.Image,
462531
Env: opts.Env,
463532
},
464533
},

0 commit comments

Comments
 (0)