From fe5b5e136d54463d77c372a8f5055908cee937a1 Mon Sep 17 00:00:00 2001 From: Manabu McCloskey Date: Mon, 26 Aug 2024 20:06:33 +0000 Subject: [PATCH] ensure ingress port is available Signed-off-by: Manabu McCloskey --- pkg/kind/cluster.go | 61 +++++++++++++++++-- pkg/kind/cluster_test.go | 40 ++++++++++++ .../expected/necessary-port-present.yaml | 17 ++++++ .../testdata/expected/no-necessary-port.yaml | 17 ++++++ pkg/kind/testdata/necessary-port-present.yaml | 16 +++++ pkg/kind/testdata/no-necessary-port.yaml | 14 +++++ 6 files changed, 161 insertions(+), 4 deletions(-) create mode 100644 pkg/kind/testdata/expected/necessary-port-present.yaml create mode 100644 pkg/kind/testdata/expected/no-necessary-port.yaml create mode 100644 pkg/kind/testdata/necessary-port-present.yaml create mode 100644 pkg/kind/testdata/no-necessary-port.yaml diff --git a/pkg/kind/cluster.go b/pkg/kind/cluster.go index 6c474670..38984ced 100644 --- a/pkg/kind/cluster.go +++ b/pkg/kind/cluster.go @@ -6,14 +6,17 @@ import ( "fmt" "io/fs" "os" + "strconv" "strings" "github.com/cnoe-io/idpbuilder/pkg/runtime" "github.com/cnoe-io/idpbuilder/pkg/util" "sigs.k8s.io/controller-runtime/pkg/log" + kindv1alpha4 "sigs.k8s.io/kind/pkg/apis/config/v1alpha4" "sigs.k8s.io/kind/pkg/cluster" "sigs.k8s.io/kind/pkg/cluster/nodes" "sigs.k8s.io/kind/pkg/cluster/nodeutils" + "sigs.k8s.io/yaml" ) var ( @@ -66,7 +69,7 @@ func (c *Cluster) getConfig() ([]byte, error) { } if err != nil { - return []byte{}, err + return nil, fmt.Errorf("reading kind config: %w", err) } var portMappingPairs []PortMapping @@ -82,8 +85,6 @@ func (c *Cluster) getConfig() ([]byte, error) { portMappingPairs[i] = PortMapping{parts[0], parts[1]} } } - } else { - portMappingPairs = nil } var retBuff []byte @@ -92,7 +93,20 @@ func (c *Cluster) getConfig() ([]byte, error) { KubernetesVersion: c.kubeVersion, ExtraPortsMapping: portMappingPairs, }); err != nil { - return []byte{}, err + return nil, err + } + + if c.kindConfigPath != "" { + parsedCluster, err := c.ensureCorrectConfig(retBuff) + if err != nil { + return nil, fmt.Errorf("ensuring custom kind config is correct: %w", err) + } + + out, err := yaml.Marshal(parsedCluster) + if err != nil { + return nil, fmt.Errorf("marshaling custom kind cluster config: %w", err) + } + return out, nil } return retBuff, nil @@ -214,3 +228,42 @@ func (c *Cluster) Reconcile(ctx context.Context, recreate bool) error { func (c *Cluster) ExportKubeConfig(name string, internal bool) error { return c.provider.ExportKubeConfig(name, c.kubeConfigPath, internal) } + +func (c *Cluster) ensureCorrectConfig(in []byte) (kindv1alpha4.Cluster, error) { + // see pkg/kind/resources/kind.yaml.tmpl and pkg/controllers/localbuild/resources/nginx/k8s/ingress-nginx.yaml + // defines which container port we should be looking for. + containerPort := "443" + if c.cfg.Protocol == "http" { + containerPort = "80" + } + parsedCluster := kindv1alpha4.Cluster{} + err := yaml.Unmarshal(in, &parsedCluster) + if err != nil { + return kindv1alpha4.Cluster{}, fmt.Errorf("parsing kind config: %w", err) + } + + appendNecessaryPort := true +nodes: + for i := range parsedCluster.Nodes { + node := parsedCluster.Nodes[i] + for _, pm := range node.ExtraPortMappings { + if strconv.Itoa(int(pm.HostPort)) == c.cfg.Port { + appendNecessaryPort = false + break nodes + } + } + } + + if appendNecessaryPort && len(parsedCluster.Nodes) != 0 { + hp, err := strconv.Atoi(c.cfg.Port) + if err != nil { + return kindv1alpha4.Cluster{}, fmt.Errorf("converting port, %s, to int: %w", c.cfg.Port, err) + } + // either "80" or "443". No need to check for err + cp, _ := strconv.Atoi(containerPort) + + parsedCluster.Nodes[0].ExtraPortMappings = append(parsedCluster.Nodes[0].ExtraPortMappings, kindv1alpha4.PortMapping{ContainerPort: int32(cp), HostPort: int32(hp)}) + } + + return parsedCluster, nil +} diff --git a/pkg/kind/cluster_test.go b/pkg/kind/cluster_test.go index eda46025..49f7eca5 100644 --- a/pkg/kind/cluster_test.go +++ b/pkg/kind/cluster_test.go @@ -3,6 +3,7 @@ package kind import ( "context" "io" + "os" "testing" runtime "github.com/cnoe-io/idpbuilder/pkg/runtime" @@ -99,6 +100,45 @@ containerdConfigPatches: assert.YAMLEq(t, expectConfig, string(cfg)) } +func TestGetConfigCustom(t *testing.T) { + + type testCase struct { + inputPath string + outputPath string + hostPort string + Protocol string + } + + cases := []testCase{ + { + inputPath: "testdata/no-necessary-port.yaml", + outputPath: "testdata/expected/no-necessary-port.yaml", + hostPort: "8443", + Protocol: "https", + }, + { + inputPath: "testdata/necessary-port-present.yaml", + outputPath: "testdata/expected/necessary-port-present.yaml", + hostPort: "80", + Protocol: "http", + }, + } + + for _, v := range cases { + c, _ := NewCluster("testcase", "v1.26.3", "", v.inputPath, "", util.CorePackageTemplateConfig{ + Host: "cnoe.localtest.me", + Port: v.hostPort, + Protocol: v.Protocol, + }) + + b, err := c.getConfig() + assert.NoError(t, err) + expected, _ := os.ReadFile(v.outputPath) + assert.YAMLEq(t, string(expected), string(b)) + } + +} + // Mock provider for testing type mockProvider struct { mock.Mock diff --git a/pkg/kind/testdata/expected/necessary-port-present.yaml b/pkg/kind/testdata/expected/necessary-port-present.yaml new file mode 100644 index 00000000..0ba23326 --- /dev/null +++ b/pkg/kind/testdata/expected/necessary-port-present.yaml @@ -0,0 +1,17 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +networking: {} +nodes: + - role: control-plane + extraMounts: + - containerPath: /var/lib/kubelet/config.json + hostPath: ~/.docker/config.json + extraPortMappings: + - containerPort: 31337 + hostPort: 31337 + - containerPort: 31340 + hostPort: 31340 + - containerPort: 31333 + hostPort: 31333 + - containerPort: 80 + hostPort: 80 diff --git a/pkg/kind/testdata/expected/no-necessary-port.yaml b/pkg/kind/testdata/expected/no-necessary-port.yaml new file mode 100644 index 00000000..bff4ddb2 --- /dev/null +++ b/pkg/kind/testdata/expected/no-necessary-port.yaml @@ -0,0 +1,17 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +networking: {} +nodes: + - role: control-plane + extraMounts: + - containerPath: /var/lib/kubelet/config.json + hostPath: ~/.docker/config.json + extraPortMappings: + - containerPort: 31337 + hostPort: 31337 + - containerPort: 31340 + hostPort: 31340 + - containerPort: 31333 + hostPort: 31333 + - containerPort: 443 + hostPort: 8443 \ No newline at end of file diff --git a/pkg/kind/testdata/necessary-port-present.yaml b/pkg/kind/testdata/necessary-port-present.yaml new file mode 100644 index 00000000..aceee5c6 --- /dev/null +++ b/pkg/kind/testdata/necessary-port-present.yaml @@ -0,0 +1,16 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + extraMounts: + - containerPath: /var/lib/kubelet/config.json + hostPath: ~/.docker/config.json + extraPortMappings: + - containerPort: 31337 + hostPort: 31337 + - containerPort: 31340 + hostPort: 31340 + - containerPort: 31333 + hostPort: 31333 + - containerPort: 80 + hostPort: 80 diff --git a/pkg/kind/testdata/no-necessary-port.yaml b/pkg/kind/testdata/no-necessary-port.yaml new file mode 100644 index 00000000..e1d086f7 --- /dev/null +++ b/pkg/kind/testdata/no-necessary-port.yaml @@ -0,0 +1,14 @@ +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: + - role: control-plane + extraMounts: + - containerPath: /var/lib/kubelet/config.json + hostPath: ~/.docker/config.json + extraPortMappings: + - containerPort: 31337 + hostPort: 31337 + - containerPort: 31340 + hostPort: 31340 + - containerPort: 31333 + hostPort: 31333