diff --git a/common/go.mod b/common/go.mod index 0174061de..befab8272 100644 --- a/common/go.mod +++ b/common/go.mod @@ -6,6 +6,7 @@ module github.com/d2iq-labs/capi-runtime-extensions/common go 1.21 require ( + github.com/onsi/gomega v1.27.10 github.com/spf13/pflag v1.0.5 k8s.io/apiextensions-apiserver v0.28.1 k8s.io/apimachinery v0.28.1 diff --git a/common/pkg/handlers/interfaces.go b/common/pkg/handlers/interfaces.go index 75473d822..0c79c3ea5 100644 --- a/common/pkg/handlers/interfaces.go +++ b/common/pkg/handlers/interfaces.go @@ -3,75 +3,6 @@ package handlers -import ( - "context" - - "github.com/spf13/pflag" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" -) - -type NamedHandler interface { +type Named interface { Name() string } - -type FlagConfigurableHandler interface { - AddFlags(prefix string, fs *pflag.FlagSet) -} - -type BeforeClusterCreateLifecycleHandler interface { - BeforeClusterCreate( - context.Context, - *runtimehooksv1.BeforeClusterCreateRequest, - *runtimehooksv1.BeforeClusterCreateResponse, - ) -} -type AfterControlPlaneInitializedLifecycleHandler interface { - AfterControlPlaneInitialized( - context.Context, - *runtimehooksv1.AfterControlPlaneInitializedRequest, - *runtimehooksv1.AfterControlPlaneInitializedResponse, - ) -} -type BeforeClusterUpgradeLifecycleHandler interface { - BeforeClusterUpgrade( - context.Context, - *runtimehooksv1.BeforeClusterUpgradeRequest, - *runtimehooksv1.BeforeClusterUpgradeResponse, - ) -} -type AfterControlPlaneUpgradeLifecycleHandler interface { - AfterControlPlaneUpgrade( - context.Context, - *runtimehooksv1.AfterControlPlaneUpgradeRequest, - *runtimehooksv1.AfterControlPlaneUpgradeResponse, - ) -} -type BeforeClusterDeleteLifecycleHandler interface { - BeforeClusterDelete( - context.Context, - *runtimehooksv1.BeforeClusterDeleteRequest, - *runtimehooksv1.BeforeClusterDeleteResponse, - ) -} - -type DiscoverVariablesMutationHandler interface { - DiscoverVariables( - context.Context, - *runtimehooksv1.DiscoverVariablesRequest, - *runtimehooksv1.DiscoverVariablesResponse, - ) -} -type GeneratePatchesMutationHandler interface { - GeneratePatches( - context.Context, - *runtimehooksv1.GeneratePatchesRequest, - *runtimehooksv1.GeneratePatchesResponse, - ) -} -type ValidateTopologyMutationHandler interface { - ValidateTopology( - context.Context, - *runtimehooksv1.ValidateTopologyRequest, - *runtimehooksv1.ValidateTopologyResponse, - ) -} diff --git a/common/pkg/handlers/lifecycle/interfaces.go b/common/pkg/handlers/lifecycle/interfaces.go new file mode 100644 index 000000000..6dcc9dfd3 --- /dev/null +++ b/common/pkg/handlers/lifecycle/interfaces.go @@ -0,0 +1,46 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package lifecycle + +import ( + "context" + + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" +) + +type BeforeClusterCreate interface { + BeforeClusterCreate( + context.Context, + *runtimehooksv1.BeforeClusterCreateRequest, + *runtimehooksv1.BeforeClusterCreateResponse, + ) +} +type AfterControlPlaneInitialized interface { + AfterControlPlaneInitialized( + context.Context, + *runtimehooksv1.AfterControlPlaneInitializedRequest, + *runtimehooksv1.AfterControlPlaneInitializedResponse, + ) +} +type BeforeClusterUpgrade interface { + BeforeClusterUpgrade( + context.Context, + *runtimehooksv1.BeforeClusterUpgradeRequest, + *runtimehooksv1.BeforeClusterUpgradeResponse, + ) +} +type AfterControlPlaneUpgrade interface { + AfterControlPlaneUpgrade( + context.Context, + *runtimehooksv1.AfterControlPlaneUpgradeRequest, + *runtimehooksv1.AfterControlPlaneUpgradeResponse, + ) +} +type BeforeClusterDelete interface { + BeforeClusterDelete( + context.Context, + *runtimehooksv1.BeforeClusterDeleteRequest, + *runtimehooksv1.BeforeClusterDeleteResponse, + ) +} diff --git a/common/pkg/handlers/mutation/interfaces.go b/common/pkg/handlers/mutation/interfaces.go new file mode 100644 index 000000000..1a4a67d6c --- /dev/null +++ b/common/pkg/handlers/mutation/interfaces.go @@ -0,0 +1,32 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package mutation + +import ( + "context" + + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" +) + +type DiscoverVariables interface { + DiscoverVariables( + context.Context, + *runtimehooksv1.DiscoverVariablesRequest, + *runtimehooksv1.DiscoverVariablesResponse, + ) +} +type GeneratePatches interface { + GeneratePatches( + context.Context, + *runtimehooksv1.GeneratePatchesRequest, + *runtimehooksv1.GeneratePatchesResponse, + ) +} +type ValidateTopology interface { + ValidateTopology( + context.Context, + *runtimehooksv1.ValidateTopologyRequest, + *runtimehooksv1.ValidateTopologyResponse, + ) +} diff --git a/common/pkg/openapi/patterns/distribution.go b/common/pkg/openapi/patterns/distribution.go new file mode 100644 index 000000000..e2a00a8e2 --- /dev/null +++ b/common/pkg/openapi/patterns/distribution.go @@ -0,0 +1,15 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package patterns + +const ( + // See: https://github.com/distribution/reference/blob/v0.5.0/regexp.go#L53 + NameSeparator = `(?:[._]|__|[-]+)` + + // See: https://github.com/distribution/reference/blob/v0.5.0/regexp.go#L123C18-L123C65 + PathComponent = Alphanumeric + `(` + NameSeparator + Alphanumeric + `)*` + + // See: https://github.com/distribution/reference/blob/v0.5.0/regexp.go#L130 + ImageRegistry = `(` + DNS1123Subdomain + `|` + IPv6 + `)` + OptionalPort + `(/` + PathComponent + `)*` +) diff --git a/common/pkg/openapi/patterns/generic.go b/common/pkg/openapi/patterns/generic.go new file mode 100644 index 000000000..62d9645ca --- /dev/null +++ b/common/pkg/openapi/patterns/generic.go @@ -0,0 +1,9 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package patterns + +const ( + // See: https://github.com/distribution/reference/blob/v0.5.0/regexp.go#L44C2-L44C28 + Alphanumeric = `[a-z0-9]+` +) diff --git a/common/pkg/openapi/patterns/net.go b/common/pkg/openapi/patterns/net.go new file mode 100644 index 000000000..38560672e --- /dev/null +++ b/common/pkg/openapi/patterns/net.go @@ -0,0 +1,13 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package patterns + +const ( + // See: https://github.com/distribution/reference/blob/v0.5.0/regexp.go#L91 + IPv6 = `\[(?:[a-fA-F0-9:]+)\]` + + Port = `:[0-9]+` + + OptionalPort = `(` + Port + `)?` +) diff --git a/common/pkg/server/server.go b/common/pkg/server/server.go index 50fdbe8ab..2169248dd 100644 --- a/common/pkg/server/server.go +++ b/common/pkg/server/server.go @@ -15,10 +15,12 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/lifecycle" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/mutation" ) type Server struct { - allExtensionHandlers []handlers.NamedHandler + allExtensionHandlers []handlers.Named webhookPort int webhookCertDir string @@ -28,7 +30,7 @@ type Server struct { enabledHandlers []string } -func NewServer(extensionHandlers ...handlers.NamedHandler) *Server { +func NewServer(extensionHandlers ...handlers.Named) *Server { // catalog contains all information about RuntimeHooks. catalog := runtimecatalog.New() @@ -87,7 +89,7 @@ func (s *Server) Start(ctx context.Context) error { continue } - if t, ok := h.(handlers.BeforeClusterCreateLifecycleHandler); ok { + if t, ok := h.(lifecycle.BeforeClusterCreate); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.BeforeClusterCreate, Name: strings.ToLower(h.Name()), @@ -98,7 +100,7 @@ func (s *Server) Start(ctx context.Context) error { } } - if t, ok := h.(handlers.AfterControlPlaneInitializedLifecycleHandler); ok { + if t, ok := h.(lifecycle.AfterControlPlaneInitialized); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.AfterControlPlaneInitialized, Name: strings.ToLower(h.Name()), @@ -109,7 +111,7 @@ func (s *Server) Start(ctx context.Context) error { } } - if t, ok := h.(handlers.BeforeClusterUpgradeLifecycleHandler); ok { + if t, ok := h.(lifecycle.BeforeClusterUpgrade); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.BeforeClusterUpgrade, Name: strings.ToLower(h.Name()), @@ -120,7 +122,7 @@ func (s *Server) Start(ctx context.Context) error { } } - if t, ok := h.(handlers.AfterControlPlaneUpgradeLifecycleHandler); ok { + if t, ok := h.(lifecycle.AfterControlPlaneUpgrade); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.AfterControlPlaneUpgrade, Name: h.Name(), @@ -131,7 +133,7 @@ func (s *Server) Start(ctx context.Context) error { } } - if t, ok := h.(handlers.BeforeClusterDeleteLifecycleHandler); ok { + if t, ok := h.(lifecycle.BeforeClusterDelete); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.BeforeClusterDelete, Name: strings.ToLower(h.Name()), @@ -142,7 +144,7 @@ func (s *Server) Start(ctx context.Context) error { } } - if t, ok := h.(handlers.DiscoverVariablesMutationHandler); ok { + if t, ok := h.(mutation.DiscoverVariables); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.DiscoverVariables, Name: strings.ToLower(h.Name()), @@ -153,7 +155,7 @@ func (s *Server) Start(ctx context.Context) error { } } - if t, ok := h.(handlers.GeneratePatchesMutationHandler); ok { + if t, ok := h.(mutation.GeneratePatches); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.GeneratePatches, Name: strings.ToLower(h.Name()), @@ -164,7 +166,7 @@ func (s *Server) Start(ctx context.Context) error { } } - if t, ok := h.(handlers.ValidateTopologyMutationHandler); ok { + if t, ok := h.(mutation.ValidateTopology); ok { if err := webhookServer.AddExtensionHandler(server.ExtensionHandler{ Hook: runtimehooksv1.ValidateTopology, Name: strings.ToLower(h.Name()), diff --git a/common/pkg/testutils/capitest/variables.go b/common/pkg/testutils/capitest/variables.go new file mode 100644 index 000000000..95065a343 --- /dev/null +++ b/common/pkg/testutils/capitest/variables.go @@ -0,0 +1,83 @@ +// Copyright 2023 D2iQ, Inc. All rights reserved. +// SPDX-License-Identifier: Apache-2.0 + +package capitest + +import ( + "context" + "encoding/json" + "testing" + + "github.com/onsi/gomega" + "github.com/onsi/gomega/gstruct" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/util/validation/field" + clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" + runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/mutation" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/testutils/openapi" +) + +type VariableTestDef struct { + Name string + Vals any + ExpectError bool +} + +func ValidateVariable[T mutation.DiscoverVariables]( + t *testing.T, + variableName string, + variableSchema *clusterv1.VariableSchema, + handlerCreator func() T, + variableTestDefs ...VariableTestDef, +) { + t.Helper() + + t.Parallel() + + for idx := range variableTestDefs { + tt := variableTestDefs[idx] + + t.Run(tt.Name, func(t *testing.T) { + t.Parallel() + + g := gomega.NewWithT(t) + h := handlerCreator() + resp := &runtimehooksv1.DiscoverVariablesResponse{} + h.DiscoverVariables( + context.Background(), + &runtimehooksv1.DiscoverVariablesRequest{}, + resp, + ) + + g.Expect(resp.Status).To(gomega.Equal(runtimehooksv1.ResponseStatusSuccess)) + g.Expect(resp.Variables).To(gomega.HaveLen(1)) + + variable := resp.Variables[0] + g.Expect(variable).To(gstruct.MatchFields(gstruct.IgnoreExtras, gstruct.Fields{ + "Name": gomega.Equal(variableName), + "Required": gomega.BeFalse(), + "Schema": gomega.Equal(*variableSchema), + })) + + encodedVals, err := json.Marshal(tt.Vals) + g.Expect(err).NotTo(gomega.HaveOccurred()) + + validateErr := openapi.ValidateClusterVariable( + &clusterv1.ClusterVariable{ + Name: variableName, + Value: apiextensionsv1.JSON{Raw: encodedVals}, + }, + &variable, + field.NewPath(variableName), + ).ToAggregate() + + if tt.ExpectError { + g.Expect(validateErr).To(gomega.HaveOccurred()) + } else { + g.Expect(validateErr).NotTo(gomega.HaveOccurred()) + } + }) + } +} diff --git a/docs/content/http-proxy.md b/docs/content/http-proxy.md index 8b1c03ba4..1e7c9b753 100644 --- a/docs/content/http-proxy.md +++ b/docs/content/http-proxy.md @@ -34,10 +34,10 @@ spec: - name: proxy value: http: http://example.com - https: http://example.com + https: https://example.com no: - - http://no-proxy-1.example.com - - http://no-proxy-2.example.com + - no-proxy-1.example.com + - no-proxy-2.example.com ``` Applying this configuration will result in new bootstrap files on the `KubeadmControlPlaneTemplate` diff --git a/go.mod b/go.mod index ef993ba1c..765747ca0 100644 --- a/go.mod +++ b/go.mod @@ -21,6 +21,7 @@ require ( k8s.io/client-go v0.28.1 k8s.io/component-base v0.28.1 k8s.io/klog/v2 v2.100.1 + k8s.io/utils v0.0.0-20230726121419-3b25d923346b sigs.k8s.io/cluster-api v1.5.1 sigs.k8s.io/controller-runtime v0.16.1 ) @@ -88,7 +89,6 @@ require ( k8s.io/apiserver v0.28.1 // indirect k8s.io/cluster-bootstrap v0.27.2 // indirect k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect - k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect sigs.k8s.io/yaml v1.3.0 // indirect diff --git a/go.sum b/go.sum index 992cd0277..b59852a6a 100644 --- a/go.sum +++ b/go.sum @@ -512,8 +512,8 @@ k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg= k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ= k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk= -k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b h1:sgn3ZU783SCgtaSJjpcVVlRqd6GSnlTLKgpAAttJvpI= +k8s.io/utils v0.0.0-20230726121419-3b25d923346b/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= sigs.k8s.io/cluster-api v1.5.1 h1:+oO4EbVQcbBJr5wjqmdjvewPHSTbVLigXZqPk3ZO8t0= sigs.k8s.io/cluster-api v1.5.1/go.mod h1:EGJUNpFWi7dF426tO8MG/jE+w7T0UO5KyMnOwQ5riUY= diff --git a/pkg/handlers/auditpolicy/inject.go b/pkg/handlers/auditpolicy/inject.go index a2ed10e6f..1618d86c5 100644 --- a/pkg/handlers/auditpolicy/inject.go +++ b/pkg/handlers/auditpolicy/inject.go @@ -18,6 +18,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/mutation" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/patches" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/patches/selectors" ) @@ -32,8 +33,8 @@ type auditPolicyPatchHandler struct { } var ( - _ handlers.NamedHandler = &auditPolicyPatchHandler{} - _ handlers.GeneratePatchesMutationHandler = &auditPolicyPatchHandler{} + _ handlers.Named = &auditPolicyPatchHandler{} + _ mutation.GeneratePatches = &auditPolicyPatchHandler{} //go:embed embedded/apiserver-audit-policy.yaml auditPolicy string diff --git a/pkg/handlers/cni/calico/handler.go b/pkg/handlers/cni/calico/handler.go index 335109d46..269605f1c 100644 --- a/pkg/handlers/cni/calico/handler.go +++ b/pkg/handlers/cni/calico/handler.go @@ -24,6 +24,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/lifecycle" "github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/cni" "github.com/d2iq-labs/capi-runtime-extensions/pkg/k8s/client" "github.com/d2iq-labs/capi-runtime-extensions/pkg/k8s/parser" @@ -70,8 +71,8 @@ type CalicoCNI struct { } var ( - _ handlers.NamedHandler = &CalicoCNI{} - _ handlers.AfterControlPlaneInitializedLifecycleHandler = &CalicoCNI{} + _ handlers.Named = &CalicoCNI{} + _ lifecycle.AfterControlPlaneInitialized = &CalicoCNI{} calicoInstallationGK = schema.GroupKind{Group: "operator.tigera.io", Kind: "Installation"} ) diff --git a/pkg/handlers/extraapiservercertsans/inject.go b/pkg/handlers/extraapiservercertsans/inject.go index 5d3350020..84fba2548 100644 --- a/pkg/handlers/extraapiservercertsans/inject.go +++ b/pkg/handlers/extraapiservercertsans/inject.go @@ -18,6 +18,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/mutation" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/patches" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/patches/selectors" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/variables" @@ -33,8 +34,8 @@ type extraAPIServerCertSANsPatchHandler struct { } var ( - _ handlers.NamedHandler = &extraAPIServerCertSANsPatchHandler{} - _ handlers.GeneratePatchesMutationHandler = &extraAPIServerCertSANsPatchHandler{} + _ handlers.Named = &extraAPIServerCertSANsPatchHandler{} + _ mutation.GeneratePatches = &extraAPIServerCertSANsPatchHandler{} ) func NewPatch() *extraAPIServerCertSANsPatchHandler { diff --git a/pkg/handlers/extraapiservercertsans/variables.go b/pkg/handlers/extraapiservercertsans/variables.go index 05d748953..c5cf8fe45 100644 --- a/pkg/handlers/extraapiservercertsans/variables.go +++ b/pkg/handlers/extraapiservercertsans/variables.go @@ -10,12 +10,13 @@ import ( runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/mutation" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/openapi/patterns" ) var ( - _ handlers.NamedHandler = &extraAPIServerCertSANsVariableHandler{} - _ handlers.DiscoverVariablesMutationHandler = &extraAPIServerCertSANsVariableHandler{} + _ handlers.Named = &extraAPIServerCertSANsVariableHandler{} + _ mutation.DiscoverVariables = &extraAPIServerCertSANsVariableHandler{} ) const ( diff --git a/pkg/handlers/extraapiservercertsans/variables_test.go b/pkg/handlers/extraapiservercertsans/variables_test.go index 3881cbe4b..e054a32a4 100644 --- a/pkg/handlers/extraapiservercertsans/variables_test.go +++ b/pkg/handlers/extraapiservercertsans/variables_test.go @@ -4,82 +4,32 @@ package extraapiservercertsans import ( - "context" - "encoding/json" "testing" - . "github.com/onsi/gomega" - . "github.com/onsi/gomega/gstruct" - apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" - "k8s.io/apimachinery/pkg/util/validation/field" - clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + "k8s.io/utils/ptr" - "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/testutils/openapi" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/testutils/capitest" ) -func TestVariableValidation_extraAPIServerCertSANs(t *testing.T) { - t.Parallel() - - tests := []struct { - name string - vals []string - expectError bool - }{{ - name: "single valid SAN", - vals: []string{"a.b.c.example.com"}, - }, { - name: "single invalid SAN", - vals: []string{"invalid:san"}, - expectError: true, - }, { - name: "duplicate valid SANs", - vals: []string{"a.b.c.example.com", "a.b.c.example.com"}, - expectError: true, - }} - - for idx := range tests { - tt := tests[idx] - - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - - g := NewWithT(t) - h := NewVariable() - resp := &runtimehooksv1.DiscoverVariablesResponse{} - h.DiscoverVariables( - context.Background(), - &runtimehooksv1.DiscoverVariablesRequest{}, - resp, - ) - - g.Expect(resp.Status).To(Equal(runtimehooksv1.ResponseStatusSuccess)) - g.Expect(resp.Variables).To(HaveLen(1)) - - variable := resp.Variables[0] - g.Expect(variable).To(MatchFields(IgnoreExtras, Fields{ - "Name": Equal(VariableName), - "Required": BeFalse(), - "Schema": Equal(ExtraAPIServerCertSANsVariables{}.VariableSchema()), - })) - - encodedVals, err := json.Marshal(tt.vals) - g.Expect(err).NotTo(HaveOccurred()) - - validateErr := openapi.ValidateClusterVariable( - &clusterv1.ClusterVariable{ - Name: VariableName, - Value: apiextensionsv1.JSON{Raw: encodedVals}, - }, - &variable, - field.NewPath(VariableName), - ).ToAggregate() - - if tt.expectError { - g.Expect(validateErr).To(HaveOccurred()) - } else { - g.Expect(validateErr).NotTo(HaveOccurred()) - } - }) - } +func TestVariableValidation(t *testing.T) { + capitest.ValidateVariable( + t, + VariableName, + ptr.To(ExtraAPIServerCertSANsVariables{}.VariableSchema()), + NewVariable, + capitest.VariableTestDef{ + Name: "single valid SAN", + Vals: []string{"a.b.c.example.com"}, + }, + capitest.VariableTestDef{ + Name: "single invalid SAN", + Vals: []string{"invalid:san"}, + ExpectError: true, + }, + capitest.VariableTestDef{ + Name: "duplicate valid SANs", + Vals: []string{"a.b.c.example.com", "a.b.c.example.com"}, + ExpectError: true, + }, + ) } diff --git a/pkg/handlers/httpproxy/inject.go b/pkg/handlers/httpproxy/inject.go index c164330c2..55a90f701 100644 --- a/pkg/handlers/httpproxy/inject.go +++ b/pkg/handlers/httpproxy/inject.go @@ -17,6 +17,7 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/mutation" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/patches" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/patches/selectors" "github.com/d2iq-labs/capi-runtime-extensions/pkg/capi/clustertopology/variables" @@ -32,8 +33,8 @@ type httpProxyPatchHandler struct { } var ( - _ handlers.NamedHandler = &httpProxyPatchHandler{} - _ handlers.GeneratePatchesMutationHandler = &httpProxyPatchHandler{} + _ handlers.Named = &httpProxyPatchHandler{} + _ mutation.GeneratePatches = &httpProxyPatchHandler{} ) func NewPatch() *httpProxyPatchHandler { diff --git a/pkg/handlers/httpproxy/inject_test.go b/pkg/handlers/httpproxy/inject_test.go index 5937a7b8e..906465959 100644 --- a/pkg/handlers/httpproxy/inject_test.go +++ b/pkg/handlers/httpproxy/inject_test.go @@ -40,7 +40,7 @@ func TestGeneratePatches_KubeadmControlPlaneTemplate(t *testing.T) { newVariable(httpproxy.VariableName, httpproxy.HTTPProxyVariables{ HTTP: "http://example.com", HTTPS: "https://example.com", - NO: []string{"https://no-proxy.example.com"}, + No: []string{"https://no-proxy.example.com"}, }), }, Items: []runtimehooksv1.GeneratePatchesRequestItem{ @@ -90,7 +90,7 @@ func TestGeneratePatches_KubeadmConfigTemplate(t *testing.T) { newVariable(httpproxy.VariableName, httpproxy.HTTPProxyVariables{ HTTP: "http://example.com", HTTPS: "https://example.com", - NO: []string{"https://no-proxy.example.com"}, + No: []string{"https://no-proxy.example.com"}, }), newVariable("builtin", map[string]any{ "machineDeployment": map[string]any{ diff --git a/pkg/handlers/httpproxy/systemd_proxy_config.go b/pkg/handlers/httpproxy/systemd_proxy_config.go index a6054793a..dbb612861 100644 --- a/pkg/handlers/httpproxy/systemd_proxy_config.go +++ b/pkg/handlers/httpproxy/systemd_proxy_config.go @@ -27,7 +27,7 @@ var ( ) func generateSystemdFiles(vars HTTPProxyVariables) []bootstrapv1.File { - if vars.HTTP == "" && vars.HTTPS == "" && len(vars.NO) == 0 { + if vars.HTTP == "" && vars.HTTPS == "" && len(vars.No) == 0 { return nil } @@ -38,7 +38,7 @@ func generateSystemdFiles(vars HTTPProxyVariables) []bootstrapv1.File { }{ HTTP: vars.HTTP, HTTPS: vars.HTTPS, - NO: strings.Join(vars.NO, ","), + NO: strings.Join(vars.No, ","), } var buf bytes.Buffer diff --git a/pkg/handlers/httpproxy/systemd_proxy_config_test.go b/pkg/handlers/httpproxy/systemd_proxy_config_test.go index 6c2361eb8..158b2dc0f 100644 --- a/pkg/handlers/httpproxy/systemd_proxy_config_test.go +++ b/pkg/handlers/httpproxy/systemd_proxy_config_test.go @@ -24,7 +24,7 @@ func TestGenerateSystemdFiles(t *testing.T) { vars: HTTPProxyVariables{ HTTP: "http://example.com", HTTPS: "https://example.com", - NO: []string{ + No: []string{ "https://no-proxy.example.com", }, }, @@ -57,7 +57,7 @@ Environment="https_proxy=https://example.com" }, { name: "no proxy only", vars: HTTPProxyVariables{ - NO: []string{ + No: []string{ "https://no-proxy.example.com", }, }, @@ -68,7 +68,7 @@ Environment="no_proxy=https://no-proxy.example.com" }, { name: "multiple no proxy only", vars: HTTPProxyVariables{ - NO: []string{ + No: []string{ "https://no-proxy.example.com", "https://no-proxy-1.example.com", }, diff --git a/pkg/handlers/httpproxy/variables.go b/pkg/handlers/httpproxy/variables.go index cf5ed7ed0..2f0cf28bf 100644 --- a/pkg/handlers/httpproxy/variables.go +++ b/pkg/handlers/httpproxy/variables.go @@ -10,11 +10,12 @@ import ( runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/mutation" ) var ( - _ handlers.NamedHandler = &httpProxyVariableHandler{} - _ handlers.DiscoverVariablesMutationHandler = &httpProxyVariableHandler{} + _ handlers.Named = &httpProxyVariableHandler{} + _ mutation.DiscoverVariables = &httpProxyVariableHandler{} ) const ( @@ -52,13 +53,13 @@ func (h *httpProxyVariableHandler) DiscoverVariables( // HTTPProxyVariables required for providing proxy configuration. type HTTPProxyVariables struct { // HTTP proxy. - HTTP string `json:"http"` + HTTP string `json:"http,omitempty"` // HTTPS proxy. - HTTPS string `json:"https"` + HTTPS string `json:"https,omitempty"` // No Proxy list. - NO []string `json:"no"` + No []string `json:"no,omitempty"` } // VariableSchema provides Cluster Class variable schema definition. diff --git a/pkg/handlers/httpproxy/variables_test.go b/pkg/handlers/httpproxy/variables_test.go index fc16ffc28..7bf0b4c14 100644 --- a/pkg/handlers/httpproxy/variables_test.go +++ b/pkg/handlers/httpproxy/variables_test.go @@ -1,32 +1,29 @@ // Copyright 2023 D2iQ, Inc. All rights reserved. // SPDX-License-Identifier: Apache-2.0 -package httpproxy_test +package httpproxy import ( - "context" "testing" - . "github.com/onsi/gomega" - . "github.com/onsi/gomega/gstruct" - runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1" + "k8s.io/utils/ptr" - "github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/httpproxy" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/testutils/capitest" ) -func TestDiscoverVariables(t *testing.T) { - g := NewWithT(t) - h := httpproxy.NewVariable() - resp := &runtimehooksv1.DiscoverVariablesResponse{} - h.DiscoverVariables(context.Background(), &runtimehooksv1.DiscoverVariablesRequest{}, resp) - - g.Expect(resp.Status).To(Equal(runtimehooksv1.ResponseStatusSuccess)) - g.Expect(resp.Variables).To(HaveLen(1)) - - variable := resp.Variables[0] - g.Expect(variable).To(MatchFields(IgnoreExtras, Fields{ - "Name": Equal(httpproxy.VariableName), - "Required": BeFalse(), - "Schema": Equal(httpproxy.HTTPProxyVariables{}.VariableSchema()), - })) +func TestVariableValidation(t *testing.T) { + capitest.ValidateVariable( + t, + VariableName, + ptr.To(HTTPProxyVariables{}.VariableSchema()), + NewVariable, + capitest.VariableTestDef{ + Name: "valid values", + Vals: HTTPProxyVariables{ + HTTP: "http://a.b.c.example.com", + HTTPS: "https://a.b.c.example.com", + No: []string{"d.e.f.example.com"}, + }, + }, + ) } diff --git a/pkg/handlers/servicelbgc/handler.go b/pkg/handlers/servicelbgc/handler.go index bf5c8e20d..c4dbc81db 100644 --- a/pkg/handlers/servicelbgc/handler.go +++ b/pkg/handlers/servicelbgc/handler.go @@ -14,6 +14,7 @@ import ( ctrlclient "sigs.k8s.io/controller-runtime/pkg/client" "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers" + "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/handlers/lifecycle" ) type ServiceLoadBalancerGC struct { @@ -21,8 +22,8 @@ type ServiceLoadBalancerGC struct { } var ( - _ handlers.NamedHandler = &ServiceLoadBalancerGC{} - _ handlers.BeforeClusterDeleteLifecycleHandler = &ServiceLoadBalancerGC{} + _ handlers.Named = &ServiceLoadBalancerGC{} + _ lifecycle.BeforeClusterDelete = &ServiceLoadBalancerGC{} ) func New(client ctrlclient.Client) *ServiceLoadBalancerGC {