Skip to content

Commit 9b77dcb

Browse files
Validate external types with CRD spec
1 parent bf4c549 commit 9b77dcb

File tree

453 files changed

+143686
-29
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

453 files changed

+143686
-29
lines changed

nodeadm/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ clean:
4141

4242
.PHONY: crds
4343
crds: controller-gen ## Generate CustomResourceDefinition objects.
44-
$(CONTROLLER_GEN) crd paths="./..." output:crd:artifacts:config=crds/
44+
$(CONTROLLER_GEN) crd paths="./..." output:crd:artifacts:config=internal/api/bridge/crds
4545

4646
.PHONY: generate
4747
generate: generate-code generate-doc ## Generate code and documentation.

nodeadm/api/v1alpha1/nodeconfig_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,15 +39,19 @@ type NodeConfigSpec struct {
3939
// These details can be found using the [DescribeCluster API](https://docs.aws.amazon.com/eks/latest/APIReference/API_DescribeCluster.html).
4040
type ClusterDetails struct {
4141
// Name is the name of your EKS cluster
42+
// +kubebuilder:validation:Required
4243
Name string `json:"name,omitempty"`
4344

4445
// APIServerEndpoint is the URL of your EKS cluster's kube-apiserver.
46+
// +kubebuilder:validation:Required
4547
APIServerEndpoint string `json:"apiServerEndpoint,omitempty"`
4648

4749
// CertificateAuthority is a base64-encoded string of your cluster's certificate authority chain.
50+
// +kubebuilder:validation:Required
4851
CertificateAuthority []byte `json:"certificateAuthority,omitempty"`
4952

5053
// CIDR is your cluster's Pod IP CIDR. This value is used to infer your cluster's DNS address.
54+
// +kubebuilder:validation:Required
5155
CIDR string `json:"cidr,omitempty"`
5256

5357
// EnableOutpost determines how your node is configured when running on an AWS Outpost.

nodeadm/go.mod

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,35 @@ require (
1515
github.com/stretchr/testify v1.8.4
1616
go.uber.org/zap v1.26.0
1717
golang.org/x/mod v0.14.0
18-
k8s.io/apimachinery v0.29.1
18+
k8s.io/apiextensions-apiserver v0.29.2
19+
k8s.io/apimachinery v0.29.2
1920
k8s.io/cri-api v0.29.1
2021
k8s.io/kubelet v0.29.1
2122
sigs.k8s.io/controller-runtime v0.17.0
2223
)
2324

2425
require (
2526
github.com/Microsoft/go-winio v0.6.1 // indirect
27+
github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect
28+
github.com/asaskevich/govalidator v0.0.0-20190424111038-f61b66f89f4a // indirect
29+
github.com/go-openapi/jsonpointer v0.19.6 // indirect
30+
github.com/go-openapi/jsonreference v0.20.2 // indirect
31+
github.com/go-openapi/swag v0.22.3 // indirect
2632
github.com/golang/protobuf v1.5.3 // indirect
33+
github.com/google/cel-go v0.17.7 // indirect
34+
github.com/google/gnostic-models v0.6.8 // indirect
35+
github.com/josharian/intern v1.0.0 // indirect
36+
github.com/mailru/easyjson v0.7.7 // indirect
37+
github.com/stoewer/go-strcase v1.2.0 // indirect
2738
github.com/stretchr/objx v0.5.0 // indirect
39+
golang.org/x/exp v0.0.0-20220722155223-a9213eeb770e // indirect
2840
golang.org/x/tools v0.16.1 // indirect
41+
google.golang.org/genproto/googleapis/api v0.0.0-20230726155614-23370e0ffb3e // indirect
2942
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
3043
google.golang.org/grpc v1.58.3 // indirect
31-
k8s.io/component-base v0.29.1 // indirect
44+
k8s.io/apiserver v0.29.2 // indirect
45+
k8s.io/component-base v0.29.2 // indirect
46+
k8s.io/kube-openapi v0.0.0-20231010175941-2dd684a91f00 // indirect
3247
)
3348

3449
require dario.cat/mergo v1.0.0 // direct
@@ -74,7 +89,7 @@ require (
7489
gopkg.in/inf.v0 v0.9.1 // indirect
7590
gopkg.in/yaml.v2 v2.4.0 // indirect
7691
gopkg.in/yaml.v3 v3.0.1 // indirect
77-
k8s.io/api v0.29.1
92+
k8s.io/api v0.29.2
7893
k8s.io/klog/v2 v2.110.1 // indirect
7994
k8s.io/utils v0.0.0-20240102154912-e7106e64919e // direct
8095
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect

nodeadm/go.sum

Lines changed: 100 additions & 6 deletions
Large diffs are not rendered by default.

nodeadm/crds/node.eks.aws_nodeconfigs.yaml renamed to nodeadm/internal/api/bridge/crds/node.eks.aws_nodeconfigs.yaml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,11 @@ spec:
6161
name:
6262
description: Name is the name of your EKS cluster
6363
type: string
64+
required:
65+
- apiServerEndpoint
66+
- certificateAuthority
67+
- cidr
68+
- name
6469
type: object
6570
containerd:
6671
description: ContainerdOptions are additional parameters passed to

nodeadm/internal/api/bridge/decode.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ func DecodeNodeConfig(data []byte) (*internalapi.NodeConfig, error) {
2828
if gvk.Group != api.GroupName {
2929
return nil, fmt.Errorf("failed to decode %q, unexpected group: %s", gvk.Kind, gvk.Group)
3030
}
31+
if err := ValidateExternalType(obj, *gvk); err != nil {
32+
return nil, err
33+
}
3134
if internalConfig, ok := obj.(*internalapi.NodeConfig); ok {
3235
return internalConfig, nil
3336
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package bridge
2+
3+
import (
4+
_ "embed"
5+
"errors"
6+
"fmt"
7+
"log"
8+
9+
"k8s.io/apiextensions-apiserver/pkg/apihelpers"
10+
apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions"
11+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
12+
apiservervalidation "k8s.io/apiextensions-apiserver/pkg/apiserver/validation"
13+
"k8s.io/apimachinery/pkg/runtime"
14+
"k8s.io/apimachinery/pkg/runtime/schema"
15+
"k8s.io/apimachinery/pkg/runtime/serializer"
16+
)
17+
18+
//go:embed crds/node.eks.aws_nodeconfigs.yaml
19+
var customResourceDefinitionYAML []byte
20+
21+
var customResourceDefinition *apiextensionsv1.CustomResourceDefinition
22+
23+
func init() {
24+
scheme := runtime.NewScheme()
25+
if err := apiextensions.AddToScheme(scheme); err != nil {
26+
panic("Failed to register apiextensions on validation scheme")
27+
}
28+
if err := apiextensionsv1.AddToScheme(scheme); err != nil {
29+
panic("Failed to register apiextensionsv1 on validation scheme")
30+
}
31+
codecs := serializer.NewCodecFactory(scheme)
32+
obj, gvk, err := codecs.UniversalDeserializer().Decode(customResourceDefinitionYAML, nil, nil)
33+
if err != nil {
34+
log.Fatalf("failed to decode CRD: %v", err)
35+
}
36+
if crd, ok := obj.(*apiextensionsv1.CustomResourceDefinition); !ok {
37+
log.Fatalf("CRD YAML is not a valid apiextensionsv1.CustomResourceDefinition: %v", gvk)
38+
} else {
39+
customResourceDefinition = crd
40+
}
41+
}
42+
43+
func ValidateExternalType(obj runtime.Object, gvk schema.GroupVersionKind) error {
44+
validationSchema, err := apihelpers.GetSchemaForVersion(customResourceDefinition, gvk.Version)
45+
if err != nil {
46+
return err
47+
}
48+
var internalSchemaProps *apiextensions.JSONSchemaProps
49+
var internalValidationSchema *apiextensions.CustomResourceValidation
50+
if validationSchema != nil {
51+
internalValidationSchema = &apiextensions.CustomResourceValidation{}
52+
if err := apiextensionsv1.Convert_v1_CustomResourceValidation_To_apiextensions_CustomResourceValidation(validationSchema, internalValidationSchema, nil); err != nil {
53+
return fmt.Errorf("failed to convert CRD validation to internal version: %v", err)
54+
}
55+
internalSchemaProps = internalValidationSchema.OpenAPIV3Schema
56+
}
57+
validator, _, err := apiservervalidation.NewSchemaValidator(internalSchemaProps)
58+
if err != nil {
59+
return err
60+
}
61+
res := validator.Validate(obj)
62+
if len(res.Errors) > 0 {
63+
return errors.Join(res.Errors...)
64+
}
65+
return nil
66+
}

nodeadm/internal/api/validation.go

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,21 +3,9 @@ package api
33
import "fmt"
44

55
func ValidateNodeConfig(cfg *NodeConfig) error {
6-
if cfg.Spec.Cluster.Name == "" {
7-
return fmt.Errorf("Name is missing in cluster configuration")
8-
}
9-
if cfg.Spec.Cluster.APIServerEndpoint == "" {
10-
return fmt.Errorf("Apiserver endpoint is missing in cluster configuration")
11-
}
12-
if cfg.Spec.Cluster.CertificateAuthority == nil {
13-
return fmt.Errorf("Certificate authority is missing in cluster configuration")
14-
}
15-
if cfg.Spec.Cluster.CIDR == "" {
16-
return fmt.Errorf("CIDR is missing in cluster configuration")
17-
}
186
if enabled := cfg.Spec.Cluster.EnableOutpost; enabled != nil && *enabled {
197
if cfg.Spec.Cluster.ID == "" {
20-
return fmt.Errorf("CIDR is missing in cluster configuration")
8+
return fmt.Errorf("cidr is missing in cluster configuration")
219
}
2210
}
2311
return nil

nodeadm/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/LICENSE

Lines changed: 26 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

nodeadm/vendor/github.com/antlr/antlr4/runtime/Go/antlr/v4/antlrdoc.go

Lines changed: 68 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)