Skip to content

Commit

Permalink
KO-130: Added support for adding custom interfaces (#200)
Browse files Browse the repository at this point in the history
* Added support for custom interface type
  • Loading branch information
abhishekdwivedi3060 committed Mar 29, 2023
1 parent 04515d0 commit da076b3
Show file tree
Hide file tree
Showing 13 changed files with 1,227 additions and 123 deletions.
46 changes: 45 additions & 1 deletion api/v1beta1/aerospikecluster_mutating_webhook.go
Expand Up @@ -60,7 +60,7 @@ func (c *AerospikeCluster) Default() admission.Response {

func (c *AerospikeCluster) setDefaults(asLog logr.Logger) error {
// Set network defaults
c.Spec.AerospikeNetworkPolicy.SetDefaults()
c.Spec.AerospikeNetworkPolicy.setDefaults(c.ObjectMeta.Namespace)

// Set common storage defaults.
c.Spec.Storage.SetDefaults()
Expand Down Expand Up @@ -284,6 +284,37 @@ func (c *AerospikeCluster) setDefaultAerospikeConfigs(
return nil
}

// setDefaults applies default to unspecified fields on the network policy.
func (n *AerospikeNetworkPolicy) setDefaults(namespace string) {
if n.AccessType == AerospikeNetworkTypeUnspecified {
n.AccessType = AerospikeNetworkTypeHostInternal
}

if n.AlternateAccessType == AerospikeNetworkTypeUnspecified {
n.AlternateAccessType = AerospikeNetworkTypeHostExternal
}

if n.TLSAccessType == AerospikeNetworkTypeUnspecified {
n.TLSAccessType = AerospikeNetworkTypeHostInternal
}

if n.TLSAlternateAccessType == AerospikeNetworkTypeUnspecified {
n.TLSAlternateAccessType = AerospikeNetworkTypeHostExternal
}

// Set network namespace if not present
n.setNetworkNamespace(namespace)
}

func (n *AerospikeNetworkPolicy) setNetworkNamespace(namespace string) {
setNamespaceDefault(n.CustomAccessNetworkNames, namespace)
setNamespaceDefault(n.CustomAlternateAccessNetworkNames, namespace)
setNamespaceDefault(n.CustomTLSAccessNetworkNames, namespace)
setNamespaceDefault(n.CustomTLSAlternateAccessNetworkNames, namespace)
setNamespaceDefault(n.CustomFabricNetworkNames, namespace)
setNamespaceDefault(n.CustomTLSFabricNetworkNames, namespace)
}

// *****************************************************************************
// Helper
// *****************************************************************************
Expand Down Expand Up @@ -746,3 +777,16 @@ func escapeString(str string) string {

return str
}

func setNamespaceDefault(networks []string, namespace string) {
for idx := range networks {
netName := strings.TrimSpace(networks[idx])
namespacedName := strings.Split(netName, "/")

if len(namespacedName) == 1 {
netName = namespace + "/" + netName
}

networks[idx] = netName
}
}
97 changes: 78 additions & 19 deletions api/v1beta1/aerospikecluster_types.go
Expand Up @@ -718,7 +718,6 @@ type AerospikeClusterStatus struct { //nolint:govet // for readability
}

// AerospikeNetworkType specifies the type of network address to use.
// +kubebuilder:validation:Enum=pod;hostInternal;hostExternal;configuredIP
// +k8s:openapi-gen=true
type AerospikeNetworkType string

Expand All @@ -743,44 +742,104 @@ const (
// label "aerospike.com/configured-access-address" in k8s node will be used as `accessAddress`
// label "aerospike.com/configured-alternate-access-address" in k8s node will be used as `alternateAccessAddress`
AerospikeNetworkTypeConfigured AerospikeNetworkType = "configuredIP"

// AerospikeNetworkTypeCustomInterface specifies any other custom interface to be used with Aerospike
AerospikeNetworkTypeCustomInterface AerospikeNetworkType = "customInterface"
)

// AerospikeNetworkPolicy specifies how clients and tools access the Aerospike cluster.
type AerospikeNetworkPolicy struct {
// AccessType is the type of network address to use for Aerospike access address.
// Defaults to hostInternal.
// +kubebuilder:validation:Enum=pod;hostInternal;hostExternal;configuredIP;customInterface
AccessType AerospikeNetworkType `json:"access,omitempty"`

// CustomAccessNetworkNames is the list of the pod's network interfaces used for Aerospike access address.
// Each element in the list is specified with a namespace and the name of a NetworkAttachmentDefinition,
// separated by a forward slash (/).
// These elements must be defined in the pod annotation k8s.v1.cni.cncf.io/networks in order to assign
// network interfaces to the pod.
// Required with 'customInterface' access type.
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:MaxItems:=1
CustomAccessNetworkNames []string `json:"customAccessNetworkNames,omitempty"`

// AlternateAccessType is the type of network address to use for Aerospike alternate access address.
// Defaults to hostExternal.
// +kubebuilder:validation:Enum=pod;hostInternal;hostExternal;configuredIP;customInterface
AlternateAccessType AerospikeNetworkType `json:"alternateAccess,omitempty"`

// CustomAlternateAccessNetworkNames is the list of the pod's network interfaces used for Aerospike
// alternate access address.
// Each element in the list is specified with a namespace and the name of a NetworkAttachmentDefinition,
// separated by a forward slash (/).
// These elements must be defined in the pod annotation k8s.v1.cni.cncf.io/networks in order to assign
// network interfaces to the pod.
// Required with 'customInterface' alternateAccess type
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:MaxItems:=1
CustomAlternateAccessNetworkNames []string `json:"customAlternateAccessNetworkNames,omitempty"`

// TLSAccessType is the type of network address to use for Aerospike TLS access address.
// Defaults to hostInternal.
// +kubebuilder:validation:Enum=pod;hostInternal;hostExternal;configuredIP;customInterface
TLSAccessType AerospikeNetworkType `json:"tlsAccess,omitempty"`

// CustomTLSAccessNetworkNames is the list of the pod's network interfaces used for Aerospike TLS access address.
// Each element in the list is specified with a namespace and the name of a NetworkAttachmentDefinition,
// separated by a forward slash (/).
// These elements must be defined in the pod annotation k8s.v1.cni.cncf.io/networks in order to assign
// network interfaces to the pod.
// Required with 'customInterface' tlsAccess type
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:MaxItems:=1
CustomTLSAccessNetworkNames []string `json:"customTLSAccessNetworkNames,omitempty"`

// TLSAlternateAccessType is the type of network address to use for Aerospike TLS alternate access address.
// Defaults to hostExternal.
// +kubebuilder:validation:Enum=pod;hostInternal;hostExternal;configuredIP;customInterface
TLSAlternateAccessType AerospikeNetworkType `json:"tlsAlternateAccess,omitempty"`
}

// SetDefaults applies default to unspecified fields on the network policy.
func (n *AerospikeNetworkPolicy) SetDefaults() {
if n.AccessType == AerospikeNetworkTypeUnspecified {
n.AccessType = AerospikeNetworkTypeHostInternal
}

if n.AlternateAccessType == AerospikeNetworkTypeUnspecified {
n.AlternateAccessType = AerospikeNetworkTypeHostExternal
}

if n.TLSAccessType == AerospikeNetworkTypeUnspecified {
n.TLSAccessType = AerospikeNetworkTypeHostInternal
}

if n.TLSAlternateAccessType == AerospikeNetworkTypeUnspecified {
n.TLSAlternateAccessType = AerospikeNetworkTypeHostExternal
}
// CustomTLSAlternateAccessNetworkNames is the list of the pod's network interfaces used for Aerospike TLS
// alternate access address.
// Each element in the list is specified with a namespace and the name of a NetworkAttachmentDefinition,
// separated by a forward slash (/).
// These elements must be defined in the pod annotation k8s.v1.cni.cncf.io/networks in order to assign
// network interfaces to the pod.
// Required with 'customInterface' tlsAlternateAccess type
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:MaxItems:=1
CustomTLSAlternateAccessNetworkNames []string `json:"customTLSAlternateAccessNetworkNames,omitempty"`

// FabricType is the type of network address to use for Aerospike fabric address.
// Defaults is empty meaning all interfaces 'any'.
// +kubebuilder:validation:Enum:=customInterface
FabricType AerospikeNetworkType `json:"fabric,omitempty"`

// CustomFabricNetworkNames is the list of the pod's network interfaces used for Aerospike fabric address.
// Each element in the list is specified with a namespace and the name of a NetworkAttachmentDefinition,
// separated by a forward slash (/).
// These elements must be defined in the pod annotation k8s.v1.cni.cncf.io/networks in order to assign
// network interfaces to the pod.
// Required with 'customInterface' fabric type
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:MaxItems:=1
CustomFabricNetworkNames []string `json:"customFabricNetworkNames,omitempty"`

// TLSFabricType is the type of network address to use for Aerospike TLS fabric address.
// Defaults is empty meaning all interfaces 'any'.
// +kubebuilder:validation:Enum:=customInterface
TLSFabricType AerospikeNetworkType `json:"tlsFabric,omitempty"`

// CustomTLSFabricNetworkNames is the list of the pod's network interfaces used for Aerospike TLS fabric address.
// Each element in the list is specified with a namespace and the name of a NetworkAttachmentDefinition,
// separated by a forward slash (/).
// These elements must be defined in the pod annotation k8s.v1.cni.cncf.io/networks in order to assign network
// interfaces to the pod.
// Required with 'customInterface' tlsFabric type
// +kubebuilder:validation:MinItems:=1
// +kubebuilder:validation:MaxItems:=1
CustomTLSFabricNetworkNames []string `json:"customTLSFabricNetworkNames,omitempty"`
}

// AerospikeInstanceSummary defines the observed state of a pod's Aerospike Server Instance.
Expand Down
113 changes: 113 additions & 0 deletions api/v1beta1/aerospikecluster_validating_webhook.go
Expand Up @@ -111,6 +111,12 @@ func (c *AerospikeCluster) ValidateUpdate(oldObj runtime.Object) error {
return fmt.Errorf("cannot update MultiPodPerHost setting")
}

if err := validateNetworkPolicyUpdate(
&old.Spec.AerospikeNetworkPolicy, &c.Spec.AerospikeNetworkPolicy,
); err != nil {
return err
}

// Validate AerospikeConfig update
if err := validateAerospikeConfigUpdate(
aslog, incomingVersion, outgoingVersion,
Expand Down Expand Up @@ -252,6 +258,10 @@ func (c *AerospikeCluster) validate(aslog logr.Logger) error {
return err
}

if err := c.validateNetworkPolicy(c.Namespace); err != nil {
return err
}

// Validate Sidecars
if err := c.validatePodSpec(); err != nil {
return err
Expand Down Expand Up @@ -1334,6 +1344,28 @@ func validateNetworkConnectionUpdate(
return nil
}

func validateNetworkPolicyUpdate(oldPolicy, newPolicy *AerospikeNetworkPolicy) error {
if oldPolicy.FabricType != newPolicy.FabricType {
return fmt.Errorf("cannot update fabric type")
}

if oldPolicy.TLSFabricType != newPolicy.TLSFabricType {
return fmt.Errorf("cannot update tlsFabric type")
}

if newPolicy.FabricType == AerospikeNetworkTypeCustomInterface &&
!reflect.DeepEqual(oldPolicy.CustomFabricNetworkNames, newPolicy.CustomFabricNetworkNames) {
return fmt.Errorf("cannot change/update customFabricNetworkNames")
}

if newPolicy.TLSFabricType == AerospikeNetworkTypeCustomInterface &&
!reflect.DeepEqual(oldPolicy.CustomTLSFabricNetworkNames, newPolicy.CustomTLSFabricNetworkNames) {
return fmt.Errorf("cannot change/update customTLSFabricNetworkNames")
}

return nil
}

func validateNsConfUpdate(newConfSpec, oldConfSpec, currentStatus *AerospikeConfigSpec) error {
newConf := newConfSpec.Value
oldConf := oldConfSpec.Value
Expand Down Expand Up @@ -1833,3 +1865,84 @@ func validateDNS(dnsPolicy v1.DNSPolicy, dnsConfig *v1.PodDNSConfig) error {

return nil
}

func (c *AerospikeCluster) validateNetworkPolicy(namespace string) error {
networkPolicy := &c.Spec.AerospikeNetworkPolicy

annotations := c.Spec.PodSpec.AerospikeObjectMeta.Annotations
networks := annotations["k8s.v1.cni.cncf.io/networks"]
networkList := strings.Split(networks, ",")
networkSet := sets.NewString()

setNamespaceDefault(networkList, namespace)

networkSet.Insert(networkList...)

validateNetworkList := func(netList []string, addressType AerospikeNetworkType, listName string) error {
if netList == nil {
return fmt.Errorf("%s is required with 'customInterface' %s type", listName, addressType)
}

if c.Spec.PodSpec.HostNetwork {
return fmt.Errorf("hostNetwork is not allowed with 'customInterface' network type")
}

if !networkSet.HasAll(netList...) {
return fmt.Errorf(
"required networks %v not present in pod metadata annotations key \"k8s.v1.cni.cncf.io/networks\"",
netList)
}

return nil
}

if networkPolicy.AccessType == AerospikeNetworkTypeCustomInterface {
if err := validateNetworkList(
networkPolicy.CustomAccessNetworkNames,
"access", "customAccessNetworkNames"); err != nil {
return err
}
}

if networkPolicy.AlternateAccessType == AerospikeNetworkTypeCustomInterface {
if err := validateNetworkList(
networkPolicy.CustomAlternateAccessNetworkNames,
"alternateAccess", "customAlternateAccessNetworkNames"); err != nil {
return err
}
}

if networkPolicy.TLSAccessType == AerospikeNetworkTypeCustomInterface {
if err := validateNetworkList(
networkPolicy.CustomTLSAccessNetworkNames,
"tlsAccess", "customTLSAccessNetworkNames"); err != nil {
return err
}
}

if networkPolicy.TLSAlternateAccessType == AerospikeNetworkTypeCustomInterface {
if err := validateNetworkList(
networkPolicy.CustomTLSAlternateAccessNetworkNames,
"tlsAlternateAccess", "customTLSAlternateAccessNetworkNames"); err != nil {
return err
}
}

if networkPolicy.FabricType == AerospikeNetworkTypeCustomInterface {
if err := validateNetworkList(
networkPolicy.CustomFabricNetworkNames,
"fabric", "customFabricNetworkNames"); err != nil {
return err
}
}

if networkPolicy.TLSFabricType == AerospikeNetworkTypeCustomInterface {
if err := validateNetworkList(
networkPolicy.CustomTLSFabricNetworkNames,
"tlsFabric", "customTLSFabricNetworkNames"); err != nil {
return err
}
}

return nil
}
4 changes: 4 additions & 0 deletions api/v1beta1/utils.go
Expand Up @@ -410,6 +410,10 @@ func GetFabricPort(aeroConf *AerospikeConfigSpec) *int {
return GetPortFromConfig(aeroConf, confKeyNetworkFabric, "port")
}

func GetFabricTLSPort(aeroConf *AerospikeConfigSpec) *int {
return GetPortFromConfig(aeroConf, confKeyNetworkFabric, "tls-port")
}

func GetPortFromConfig(
aeroConf *AerospikeConfigSpec, connectionType string, paramName string,
) *int {
Expand Down
34 changes: 32 additions & 2 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit da076b3

Please sign in to comment.