Skip to content

Commit

Permalink
feat: Add Calico CNI AWS ingress rules (#206)
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmidyson authored Oct 3, 2023
1 parent 2abf01b commit 3c91ca5
Show file tree
Hide file tree
Showing 11 changed files with 454 additions and 55 deletions.
31 changes: 7 additions & 24 deletions common/pkg/capi/apis/decoders.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,40 +5,23 @@ package apis

import (
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/runtime/serializer"
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
bootstrapv1 "sigs.k8s.io/cluster-api/bootstrap/kubeadm/api/v1beta1"
controlplanev1 "sigs.k8s.io/cluster-api/controlplane/kubeadm/api/v1beta1"

capav1 "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
capdv1 "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/external/sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1"
)

var capiCoreGroups = []schema.GroupVersion{
controlplanev1.GroupVersion,
bootstrapv1.GroupVersion,
capiv1.GroupVersion,
func DecoderForScheme(scheme *runtime.Scheme) runtime.Decoder {
return serializer.NewCodecFactory(scheme).UniversalDecoder(
scheme.PrioritizedVersionsAllGroups()...,
)
}

func CAPIDecoder() runtime.Decoder {
return serializer.NewCodecFactory(CAPIScheme()).UniversalDecoder(capiCoreGroups...)
return DecoderForScheme(CAPIScheme())
}

func CAPDDecoder() runtime.Decoder {
return serializer.NewCodecFactory(CAPDScheme()).UniversalDecoder(
append(
[]schema.GroupVersion{capdv1.GroupVersion},
capiCoreGroups...,
)...,
)
return DecoderForScheme(CAPDScheme())
}

func CAPADecoder() runtime.Decoder {
return serializer.NewCodecFactory(CAPAScheme()).UniversalDecoder(
append(
[]schema.GroupVersion{capav1.GroupVersion},
capiCoreGroups...,
)...,
)
return DecoderForScheme(CAPAScheme())
}
47 changes: 27 additions & 20 deletions common/pkg/capi/apis/schemes.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,34 +14,41 @@ import (
capdv1 "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/external/sigs.k8s.io/cluster-api/test/infrastructure/docker/api/v1beta1"
)

func CAPIScheme() *runtime.Scheme {
func NewScheme(registerFuncs ...func(*runtime.Scheme) error) *runtime.Scheme {
sb := runtime.NewSchemeBuilder(registerFuncs...)
scheme := runtime.NewScheme()

utilruntime.Must(bootstrapv1.AddToScheme(scheme))
utilruntime.Must(controlplanev1.AddToScheme(scheme))
utilruntime.Must(capiv1.AddToScheme(scheme))

utilruntime.Must(sb.AddToScheme(scheme))
return scheme
}

func CAPAScheme() *runtime.Scheme {
scheme := runtime.NewScheme()
func CAPIRegisterFuncs() []func(*runtime.Scheme) error {
return []func(*runtime.Scheme) error{
bootstrapv1.AddToScheme,
controlplanev1.AddToScheme,
capiv1.AddToScheme,
}
}

utilruntime.Must(bootstrapv1.AddToScheme(scheme))
utilruntime.Must(controlplanev1.AddToScheme(scheme))
utilruntime.Must(capiv1.AddToScheme(scheme))
utilruntime.Must(capav1.AddToScheme(scheme))
func CAPARegisterFuncs() []func(*runtime.Scheme) error {
return []func(*runtime.Scheme) error{
capav1.AddToScheme,
}
}

return scheme
func CAPDRegisterFuncs() []func(*runtime.Scheme) error {
return []func(*runtime.Scheme) error{
capdv1.AddToScheme,
}
}

func CAPDScheme() *runtime.Scheme {
scheme := runtime.NewScheme()
func CAPIScheme() *runtime.Scheme {
return NewScheme(CAPIRegisterFuncs()...)
}

utilruntime.Must(bootstrapv1.AddToScheme(scheme))
utilruntime.Must(controlplanev1.AddToScheme(scheme))
utilruntime.Must(capiv1.AddToScheme(scheme))
utilruntime.Must(capdv1.AddToScheme(scheme))
func CAPAScheme() *runtime.Scheme {
return NewScheme(append(CAPIRegisterFuncs(), CAPARegisterFuncs()...)...)
}

return scheme
func CAPDScheme() *runtime.Scheme {
return NewScheme(append(CAPIRegisterFuncs(), CAPDRegisterFuncs()...)...)
}
10 changes: 4 additions & 6 deletions common/pkg/testutils/capitest/serializer/tojson.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import (
"encoding/json"

"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
)

func ToJSON(v any) []byte {
Expand All @@ -21,12 +22,9 @@ func ToJSON(v any) []byte {
data, err = json.Marshal(v)
}

if err != nil {
panic(err)
}
utilruntime.Must(err)

compacted := &bytes.Buffer{}
if err := json.Compact(compacted, data); err != nil {
panic(err)
}
utilruntime.Must(json.Compact(compacted, data))
return compacted.Bytes()
}
184 changes: 184 additions & 0 deletions pkg/handlers/aws/mutation/cni/calico/inject.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,184 @@
// Copyright 2023 D2iQ, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package calico

import (
"context"
_ "embed"

"github.com/go-logr/logr"
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
"k8s.io/apimachinery/pkg/runtime"
runtimehooksv1 "sigs.k8s.io/cluster-api/exp/runtime/hooks/api/v1alpha1"
"sigs.k8s.io/cluster-api/exp/runtime/topologymutation"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

"github.com/d2iq-labs/capi-runtime-extensions/api/v1alpha1"
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/apis"
commonhandlers "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/handlers"
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/handlers/mutation"
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/patches"
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/patches/selectors"
"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/variables"
capav1 "github.com/d2iq-labs/capi-runtime-extensions/common/pkg/external/sigs.k8s.io/cluster-api-provider-aws/v2/api/v1beta2"
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/generic/clusterconfig"
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/generic/mutation/cni"
)

const (
// HandlerNamePatch is the name of the inject handler.
HandlerNamePatch = "CalicoCNIPatch"
)

type calicoPatchHandler struct {
variableName string
variableFieldPath []string
}

var (
_ commonhandlers.Named = &calicoPatchHandler{}
_ mutation.GeneratePatches = &calicoPatchHandler{}
_ mutation.MetaMutator = &calicoPatchHandler{}
)

func NewPatch() *calicoPatchHandler {
return newCalicoPatchHandler(cni.VariableName)
}

func NewMetaPatch() *calicoPatchHandler {
return newCalicoPatchHandler(clusterconfig.MetaVariableName, cni.VariableName)
}

func newCalicoPatchHandler(
variableName string,
variableFieldPath ...string,
) *calicoPatchHandler {
return &calicoPatchHandler{
variableName: variableName,
variableFieldPath: variableFieldPath,
}
}

func (h *calicoPatchHandler) Name() string {
return HandlerNamePatch
}

func (h *calicoPatchHandler) Mutate(
ctx context.Context,
obj runtime.Object,
vars map[string]apiextensionsv1.JSON,
holderRef runtimehooksv1.HolderReference,
_ client.ObjectKey,
) error {
log := ctrl.LoggerFrom(ctx).WithValues(
"holderRef", holderRef,
)

cniVar, found, err := variables.Get[v1alpha1.CNI](
vars,
h.variableName,
h.variableFieldPath...,
)
if err != nil {
return err
}
if !found {
log.V(5).Info("cni variable not defined")
return nil
}
if cniVar.Provider != v1alpha1.CNIProviderCalico {
log.V(5).
WithValues("cniProvider", cniVar.Provider).
Info("CNI provider not defined as Calico - skipping")
return nil
}

log = log.WithValues(
"variableName",
h.variableName,
"variableFieldPath",
h.variableFieldPath,
"variableValue",
cniVar,
)

return patches.Generate(
obj,
vars,
&holderRef,
selectors.InfrastructureCluster(capav1.GroupVersion.Version, "AWSClusterTemplate"),
log,
mutateAWSClusterTemplateFunc(log),
)
}

func (h *calicoPatchHandler) GeneratePatches(
ctx context.Context,
req *runtimehooksv1.GeneratePatchesRequest,
resp *runtimehooksv1.GeneratePatchesResponse,
) {
topologymutation.WalkTemplates(
ctx,
apis.DecoderForScheme(apis.CAPAScheme()),
req,
resp,
func(
ctx context.Context,
obj runtime.Object,
vars map[string]apiextensionsv1.JSON,
holderRef runtimehooksv1.HolderReference,
) error {
return h.Mutate(ctx, obj, vars, holderRef, client.ObjectKey{})
},
)
}

func mutateAWSClusterTemplateFunc(log logr.Logger) func(obj *capav1.AWSClusterTemplate) error {
return func(obj *capav1.AWSClusterTemplate) error {
log.WithValues(
"patchedObjectKind", obj.GetObjectKind().GroupVersionKind().String(),
"patchedObjectName", client.ObjectKeyFromObject(obj),
).Info("setting CNI ingress rules in AWS cluster spec")

if obj.Spec.Template.Spec.NetworkSpec.CNI == nil {
obj.Spec.Template.Spec.NetworkSpec.CNI = &capav1.CNISpec{}
}
obj.Spec.Template.Spec.NetworkSpec.CNI.CNIIngressRules = append(
obj.Spec.Template.Spec.NetworkSpec.CNI.CNIIngressRules,
capav1.CNIIngressRule{
Description: "typha (calico)",
Protocol: capav1.SecurityGroupProtocolTCP,
FromPort: 5473,
ToPort: 5473,
},
capav1.CNIIngressRule{
Description: "bgp (calico)",
Protocol: capav1.SecurityGroupProtocolTCP,
FromPort: 179,
ToPort: 179,
},
capav1.CNIIngressRule{
Description: "IP-in-IP (calico)",
Protocol: capav1.SecurityGroupProtocolIPinIP,
FromPort: -1,
ToPort: 65535,
},
capav1.CNIIngressRule{
Description: "node metrics (calico)",
Protocol: capav1.SecurityGroupProtocolTCP,
FromPort: 9091,
ToPort: 9091,
},
capav1.CNIIngressRule{
Description: "typha metrics (calico)",
Protocol: capav1.SecurityGroupProtocolTCP,
FromPort: 9093,
ToPort: 9093,
},
)

return nil
}
}
22 changes: 22 additions & 0 deletions pkg/handlers/aws/mutation/cni/calico/inject_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// Copyright 2023 D2iQ, Inc. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package calico

import (
"testing"

"github.com/d2iq-labs/capi-runtime-extensions/common/pkg/capi/clustertopology/handlers/mutation"
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/aws/mutation/cni/calico/tests"
"github.com/d2iq-labs/capi-runtime-extensions/pkg/handlers/generic/mutation/cni"
)

func TestGeneratePatches(t *testing.T) {
t.Parallel()

tests.TestGeneratePatches(
t,
func() mutation.GeneratePatches { return NewPatch() },
cni.VariableName,
)
}
Loading

0 comments on commit 3c91ca5

Please sign in to comment.