Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion pkg/ctl/cmdutils/configfile_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ var _ = Describe("cmdutils configfile", func() {
l.flagsIncompatibleWithConfigFile.Delete("name")

err := l.Load()
Expect(err).To(MatchError(ContainSubstring("error unmarshaling JSON: while decoding JSON: json: unknown field \"containerRuntime\"")))
Expect(err).To(MatchError(ContainSubstring("strict decoding error: unknown field \"managedNodeGroups[0].containerRuntime\"")))
})
})
})
Expand Down
16 changes: 5 additions & 11 deletions pkg/eks/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@ import (
"github.com/aws/aws-sdk-go-v2/service/sts"
"github.com/kris-nova/logger"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/serializer"
k8sclient "k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/scheme"
"sigs.k8s.io/yaml"

"github.com/weaveworks/eksctl/pkg/ami"
api "github.com/weaveworks/eksctl/pkg/apis/eksctl.io/v1alpha5"
Expand Down Expand Up @@ -217,18 +217,12 @@ func newAWSProvider(spec *api.ProviderConfig, configurationLoader AWSConfigurati
return provider, nil
}

// The default deserializer silently drops unknown and mis-cased keys.
var strictDeserializer = serializer.NewCodecFactory(scheme.Scheme, serializer.EnableStrict).UniversalDeserializer()

// ParseConfig parses data into a ClusterConfig
func ParseConfig(data []byte) (*api.ClusterConfig, error) {
// strict mode is not available in runtime.Decode, so we use the parser
// directly; we don't store the resulting object, this is just the means
// of detecting any unknown keys
// NOTE: we must use sigs.k8s.io/yaml, as it behaves differently from
// github.com/ghodss/yaml, which didn't handle nested structs well
if err := yaml.UnmarshalStrict(data, &api.ClusterConfig{}); err != nil {
return nil, err
}

obj, err := runtime.Decode(scheme.Codecs.UniversalDeserializer(), data)
obj, err := runtime.Decode(strictDeserializer, data)
if err != nil {
return nil, err
}
Expand Down
31 changes: 28 additions & 3 deletions pkg/eks/api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,19 +215,44 @@ var _ = Describe("eksctl API", func() {
It("should reject unknown field in a YAML config", func() {
_, err := eks.LoadConfigFromFile("testdata/bad-field-1.yaml")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-1.yaml": error unmarshaling JSON: while decoding JSON: json: unknown field "zone"`))
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-1.yaml": strict decoding error: unknown field "metadata.zone"`))
})

It("should reject unknown field in a YAML config", func() {
_, err := eks.LoadConfigFromFile("testdata/bad-field-2.yaml")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-2.yaml": error unmarshaling JSON: while decoding JSON: json: unknown field "bar"`))
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-2.yaml": strict decoding error: unknown field "nodeGroups[0].iam.withAddonPolicies.bar"`))
})

It("should reject unknown field in a JSON config", func() {
_, err := eks.LoadConfigFromFile("testdata/bad-field-1.json")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-1.json": error unmarshaling JSON: while decoding JSON: json: unknown field "nodes"`))
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-1.json": strict decoding error: unknown field "nodeGroups[0].nodes"`))
})

It("should reject a duplicate key in a YAML config", func() {
_, err := eks.LoadConfigFromFile("testdata/duplicate-key-1.yaml")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/duplicate-key-1.yaml": strict decoding error: yaml: unmarshal errors:`))
Expect(err.Error()).To(ContainSubstring(`key "name" already set in map`))
})

It("should report a type error before unknown fields", func() {
_, err := eks.LoadConfigFromFile("testdata/bad-type-2.yaml")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-type-2.yaml": json: cannot unmarshal bool into Go struct field`))
})

It("should reject a top-level field with the wrong case", func() {
_, err := eks.LoadConfigFromFile("testdata/bad-field-case-1.yaml")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-case-1.yaml": strict decoding error: unknown field "NodeGroups"`))
})

It("should reject a nested field with the wrong case", func() {
_, err := eks.LoadConfigFromFile("testdata/bad-field-case-2.yaml")
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(HavePrefix(`loading config file "testdata/bad-field-case-2.yaml": strict decoding error: unknown field "managedNodeGroups[0].capacityReservation.capacityReservationTarget.capacityReservationId"`))
})

It("should reject old API version", func() {
Expand Down
2 changes: 1 addition & 1 deletion pkg/eks/testdata/bad-field-1.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"apiVersion": "eksctl.io/v1alpha3",
"apiVersion": "eksctl.io/v1alpha5",
"kind": "ClusterConfig",
"metadata": {
"name": "cluster-1",
Expand Down
3 changes: 2 additions & 1 deletion pkg/eks/testdata/bad-field-2.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ nodeGroups:
- name: ng-1
instanceType: m5.large
desiredCapacity: 10
ssh: true
ssh:
allow: true
iam:
withAddonPolicies:
foo: 1
Expand Down
11 changes: 11 additions & 0 deletions pkg/eks/testdata/bad-field-case-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: cluster-1
region: eu-north-1

NodeGroups:
- name: ng-1
instanceType: m5.large
13 changes: 13 additions & 0 deletions pkg/eks/testdata/bad-field-case-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: cluster-1
region: eu-north-1

managedNodeGroups:
- name: mng-1
capacityReservation:
capacityReservationTarget:
capacityReservationId: cr-0123456789abcdef0
14 changes: 14 additions & 0 deletions pkg/eks/testdata/bad-type-2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: cluster-1
region: eu-north-1

nodeGroups:
- name: ng-1
ssh: true
iam:
withAddonPolicies:
foo: 1
8 changes: 8 additions & 0 deletions pkg/eks/testdata/duplicate-key-1.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig

metadata:
name: cluster-1
name: cluster-2
region: eu-north-1
Loading