Skip to content

Commit

Permalink
Ensure Kubernetes version is always parsed as string
Browse files Browse the repository at this point in the history
  • Loading branch information
abhay-krishna committed Jan 17, 2025
1 parent b9cdab7 commit cc55cab
Show file tree
Hide file tree
Showing 27 changed files with 72 additions and 103 deletions.
5 changes: 4 additions & 1 deletion pkg/api/v1alpha1/cluster.go
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,10 @@ type kindObject struct {
// ParseClusterConfigFromContent unmarshalls an API object implementing the KindAccessor interface
// from a multiobject yaml content. It doesn't set defaults nor validates the object.
func ParseClusterConfigFromContent(content []byte, clusterConfig KindAccessor) error {
r := yamlutil.NewYAMLReader(bufio.NewReader(bytes.NewReader(content)))
kubeVersionRegex := regexp.MustCompile(constants.KubernetesVersionRegex)
sanitizedContent := kubeVersionRegex.ReplaceAllString(string(content), constants.QuotedKubernetesVersionRegexReplacement)

r := yamlutil.NewYAMLReader(bufio.NewReader(bytes.NewReader([]byte(sanitizedContent))))
for {
d, err := r.Read()
if err == io.EOF {
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/v1alpha1/testdata/cluster_1_20.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/v1alpha1/testdata/cluster_1_20_cloudstack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
datacenterRef:
kind: CloudStackDatacenterConfig
name: eksa-unit-test
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 0
machineGroupRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
2 changes: 1 addition & 1 deletion pkg/api/v1alpha1/testdata/incorrect_indentation.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ spec:
machineGroupRef:
name: eksa-unit-test
kind: VSphereMachineConfig
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
12 changes: 8 additions & 4 deletions pkg/cluster/config_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"sigs.k8s.io/yaml"

anywherev1 "github.com/aws/eks-anywhere/pkg/api/v1alpha1"
"github.com/aws/eks-anywhere/pkg/constants"
"github.com/aws/eks-anywhere/pkg/logger"
)

Expand Down Expand Up @@ -113,7 +114,10 @@ type parsed struct {
cluster *anywherev1.Cluster
}

var separatorRegex = regexp.MustCompile(`(?m)^---$`)
var (
separatorRegex = regexp.MustCompile(`(?m)^---$`)
kubeVersionRegex = regexp.MustCompile(constants.KubernetesVersionRegex)
)

func (c *ConfigManager) unmarshal(yamlManifest []byte) (*parsed, error) {
parsed := &parsed{
Expand All @@ -122,9 +126,9 @@ func (c *ConfigManager) unmarshal(yamlManifest []byte) (*parsed, error) {
yamlObjs := separatorRegex.Split(string(yamlManifest), -1)

for _, yamlObj := range yamlObjs {
trimmedYamlObj := strings.TrimSuffix(yamlObj, "\n")
sanitizedYamlObj := kubeVersionRegex.ReplaceAllString(strings.TrimSuffix(yamlObj, "\n"), constants.QuotedKubernetesVersionRegexReplacement)
k := &basicAPIObject{}
err := yaml.Unmarshal([]byte(trimmedYamlObj), k)
err := yaml.Unmarshal([]byte(sanitizedYamlObj), k)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -154,7 +158,7 @@ func (c *ConfigManager) unmarshal(yamlManifest []byte) (*parsed, error) {
continue
}

if err := yaml.Unmarshal([]byte(trimmedYamlObj), obj); err != nil {
if err := yaml.Unmarshal([]byte(sanitizedYamlObj), obj); err != nil {
return nil, err
}
parsed.objects.add(obj)
Expand Down
2 changes: 1 addition & 1 deletion pkg/cluster/testdata/cluster_1_19.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ spec:
kind: VSphereMachineConfig
name: eksa-unit-test
- name: workers-2
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
count: 1
machineGroupRef:
kind: VSphereMachineConfig
Expand Down
2 changes: 1 addition & 1 deletion pkg/cluster/testdata/cluster_1_20_cloudstack.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
datacenterRef:
kind: CloudStackDatacenterConfig
name: eksa-unit-test
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
datacenterRef:
kind: CloudStackDatacenterConfig
name: eksa-unit-test
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
workerNodeGroupConfigurations:
- count: 3
machineGroupRef:
Expand Down
2 changes: 1 addition & 1 deletion pkg/cluster/testdata/docker_cluster_oidc_awsiam_flux.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ spec:
name: m-docker
workerNodeGroupConfigurations:
- name: workers-1
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
count: 1
identityProviderRefs:
- kind: OIDCConfig
Expand Down
7 changes: 7 additions & 0 deletions pkg/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,13 @@ const (
// DefaultcuratedPackagesRegistry is a containerd compatible registry format that matches all AWS regions.
DefaultCuratedPackagesRegistry = "783794618700.dkr.ecr.*.amazonaws.com"

// KubernetesVersionRegex matches the Kubernetes version field in the cluster config.
KubernetesVersionRegex = `(?m)(.*kubernetesVersion:\s*)['"]?(1\.[0-9]{2,})['"]?(.*)$`

// QuoteRegexReplacement is the target replacement pattern which will add quotes around the Kubernetes version
// in the cluster config.
QuotedKubernetesVersionRegexReplacement = `${1}"${2}"${3}`

// Provider specific env vars.
VSphereUsernameKey = "VSPHERE_USERNAME"
VSpherePasswordKey = "VSPHERE_PASSWORD"
Expand Down
2 changes: 1 addition & 1 deletion pkg/dependencies/testdata/cluster_tinkerbell.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ spec:
datacenterRef:
kind: TinkerbellDatacenterConfig
name: eksa-unit-test
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
managementCluster:
name: eksa-unit-test
workerNodeGroupConfigurations:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ spec:
workerNodeGroupConfigurations:
- count: 3
name: md-0
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
machineGroupRef:
kind: CloudStackMachineConfig
name: test-md-0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ metadata:
name: eksa-unit-test
namespace: default
spec:
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
controlPlaneConfiguration:
name: eksa-unit-test-cp
count: 3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ spec:
name: test
workerNodeGroupConfigurations:
- count: 1
kubernetesVersion: "1.20"
kubernetesVersion: 1.20
name: md-0
machineGroupRef:
name: test-md
Expand Down
23 changes: 0 additions & 23 deletions pkg/utils/yaml/yaml.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package yaml

import (
"bufio"
"bytes"
"fmt"
"io"

apiyaml "k8s.io/apimachinery/pkg/util/yaml"
"sigs.k8s.io/yaml"
)

Expand All @@ -28,23 +25,3 @@ func Serialize[T any](objs ...T) ([][]byte, error) {
}
return r, nil
}

// SplitDocuments function splits content into individual document parts represented as byte slices.
func SplitDocuments(r io.Reader) ([][]byte, error) {
resources := make([][]byte, 0)

yr := apiyaml.NewYAMLReader(bufio.NewReader(r))
for {
d, err := yr.Read()
if err == io.EOF {
break
}
if err != nil {
return nil, err
}

resources = append(resources, d)
}

return resources, nil
}
79 changes: 25 additions & 54 deletions pkg/utils/yaml/yaml_test.go
Original file line number Diff line number Diff line change
@@ -1,99 +1,70 @@
package yaml_test

import (
"bufio"
"errors"
"strings"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

yamlutil "github.com/aws/eks-anywhere/pkg/utils/yaml"
)

func TestSplitDocuments(t *testing.T) {
func TestJoinDocuments(t *testing.T) {
tests := []struct {
name string
input string
expectedDocs [][]byte
expectedErr error
name string
input [][]byte
output []byte
}{
{
name: "Empty input",
input: "",
expectedDocs: [][]byte{},
expectedErr: nil,
name: "Empty input",
input: [][]byte{},
output: []byte{},
},
{
name: "Single document",
input: `apiVersion: v1
input: [][]byte{
[]byte(`apiVersion: v1
kind: Pod
metadata:
name: pod-1
`,
expectedDocs: [][]byte{
[]byte(`apiVersion: v1
`),
},
output: []byte(`apiVersion: v1
kind: Pod
metadata:
name: pod-1
`),
},
expectedErr: nil,
},
{
name: "Multiple documents",
input: `apiVersion: v1
input: [][]byte{
[]byte(`apiVersion: v1
kind: Pod
metadata:
name: pod-1
---
apiVersion: v1
`),
[]byte(`apiVersion: v1
kind: Service
metadata:
name: service-1
`,
expectedDocs: [][]byte{
[]byte(`apiVersion: v1
`),
},
output: []byte(`apiVersion: v1
kind: Pod
metadata:
name: pod-1
`),
[]byte(`apiVersion: v1
---
apiVersion: v1
kind: Service
metadata:
name: service-1
`),
},
expectedErr: nil,
},
{
name: "Error reading input 2",
input: `---\nkey: value\ninvalid_separator\n`,
expectedDocs: nil,
expectedErr: errors.New("invalid Yaml document separator: \\nkey: value\\ninvalid_separator\\n"),
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
r := strings.NewReader(test.input)

docs, err := yamlutil.SplitDocuments(bufio.NewReader(r))
if test.expectedErr != nil {
assert.Equal(t, test.expectedErr.Error(), err.Error())
assert.Equal(t, len(test.expectedDocs), len(docs))
} else {
require.NoError(t, err)
if len(docs) != len(test.expectedDocs) {
t.Errorf("Expected %d documents, but got %d", len(test.expectedDocs), len(docs))
}

for i, doc := range docs {
if string(doc) != string(test.expectedDocs[i]) {
t.Errorf("Document %d mismatch.\nExpected:\n%s\nGot:\n%s", i+1, string(test.expectedDocs[i]), string(doc))
}
}
joinedDoc := yamlutil.Join(test.input)
if string(joinedDoc) != string(test.output) {
t.Errorf("Document mismatch.\nExpected:\n%s\nGot:\n%s", string(test.output), string(joinedDoc))
}
})
}
Expand Down
Loading

0 comments on commit cc55cab

Please sign in to comment.