Skip to content

Commit

Permalink
Allow specifying on which interface the Azure IPAM should allocate IP…
Browse files Browse the repository at this point in the history
…s on

Signed-off-by: Vlad Ungureanu <vladu@palantir.com>
  • Loading branch information
ungureanuvladvictor authored and tgraf committed Apr 9, 2020
1 parent f5425fe commit 070baff
Show file tree
Hide file tree
Showing 7 changed files with 95 additions and 5 deletions.
15 changes: 15 additions & 0 deletions pkg/azure/ipam/node.go
Expand Up @@ -29,6 +29,9 @@ import (

// Node represents a node representing an Azure instance
type Node struct {
// k8sObj is the CiliumNode custom resource representing the node
k8sObj *v2.CiliumNode

// node contains the general purpose fields of a node
node *ipam.Node

Expand All @@ -38,6 +41,7 @@ type Node struct {

// UpdatedNode is called when an update to the CiliumNode is received.
func (n *Node) UpdatedNode(obj *v2.CiliumNode) {
n.k8sObj = obj
}

// PopulateStatusFields fills in the status field of the CiliumNode custom
Expand Down Expand Up @@ -66,12 +70,23 @@ func (n *Node) ReleaseIPs(ctx context.Context, r *ipam.ReleaseAction) error {
// PrepareIPAllocation returns the number of IPs that can be allocated/created.
func (n *Node) PrepareIPAllocation(scopedLog *logrus.Entry) (a *ipam.AllocationAction, err error) {
a = &ipam.AllocationAction{}
requiredIfaceName := n.k8sObj.Spec.Azure.InterfaceName
err = n.manager.instances.ForeachInterface(n.node.InstanceID(), func(instanceID, interfaceID string, interfaceObj ipamTypes.InterfaceRevision) error {
iface, ok := interfaceObj.Resource.(*types.AzureInterface)
if !ok {
return fmt.Errorf("invalid interface object")
}

if requiredIfaceName != "" {
if iface.Name != requiredIfaceName {
scopedLog.WithFields(logrus.Fields{
"ifaceName": iface.Name,
"requiredName": requiredIfaceName,
}).Debug("Not considering interface for allocation sice it does not match the required name")
return nil
}
}

scopedLog.WithFields(logrus.Fields{
"id": iface.ID,
"numAddresses": len(iface.Addresses),
Expand Down
17 changes: 17 additions & 0 deletions pkg/azure/types/types.go
Expand Up @@ -36,6 +36,23 @@ const (
StateSucceeded = "succeeded"
)

// AzureSpec is the Azure specification of a node running via the Azure IPAM
//
// The Azure specification can either be provided explicitly by the user or the
// cilium agent running on the node can be instructed to create the CiliumNode
// custom resource along with an Azure specification when the node registers
// itself to the Kubernetes cluster.
// This struct is embedded into v2.CiliumNode
//
// +k8s:deepcopy-gen=true
type AzureSpec struct {
// InterfaceName is the name of the interface the cilium-operator
// will use to allocate all the IPs on
//
// +optional
InterfaceName string `json:"interface-name,omitempty"`
}

// AzureStatus is the status of Azure addressing of the node
//
// This struct is embedded into v2.CiliumNode
Expand Down
4 changes: 4 additions & 0 deletions pkg/k8s/apis/cilium.io/v2/register.go
Expand Up @@ -398,6 +398,10 @@ func createNodeCRD(clientset apiextensionsclient.Interface) error {
Type: "string",
Description: "instance-id is the Azure specific identifier of the node",
},
"interface-name": {
Type: "string",
Description: "interface-name represents the name of the interface on which additional IP addreses will be allocated",
},
},
},
"eni": {
Expand Down
5 changes: 5 additions & 0 deletions pkg/k8s/apis/cilium.io/v2/types.go
Expand Up @@ -673,6 +673,11 @@ type NodeSpec struct {
// +optional
ENI eniTypes.ENISpec `json:"eni,omitempty"`

// Azure is the Azure IPAM specific configuration
//
// +optional
Azure azureTypes.AzureSpec `json:"azure,omitempty"`

// IPAM is the address management specification. This section can be
// populated by a user or it can be automatically populated by an IPAM
// operator
Expand Down
12 changes: 12 additions & 0 deletions pkg/nodediscovery/nodediscovery.go
Expand Up @@ -332,6 +332,18 @@ func (n *NodeDiscovery) UpdateCiliumNodeResource() {
// returned by the Azure API. Convert it to lower case for
// consistent results.
nodeResource.Spec.InstanceID = strings.ToLower(strings.TrimPrefix(providerID, azureTypes.ProviderPrefix))

if c := n.NetConf; c != nil {
if c.IPAM.MinAllocate != 0 {
nodeResource.Spec.IPAM.MinAllocate = c.IPAM.MinAllocate
}
if c.IPAM.PreAllocate != 0 {
nodeResource.Spec.IPAM.PreAllocate = c.IPAM.PreAllocate
}
if c.Azure.InterfaceName != "" {
nodeResource.Spec.Azure.InterfaceName = c.Azure.InterfaceName
}
}
}

if performUpdate {
Expand Down
12 changes: 7 additions & 5 deletions plugins/cilium-cni/types/types.go
Expand Up @@ -21,6 +21,7 @@ import (
"net"

eniTypes "github.com/cilium/cilium/pkg/aws/eni/types"
azureTypes "github.com/cilium/cilium/pkg/azure/types"
ipamTypes "github.com/cilium/cilium/pkg/ipam/types"

cniTypes "github.com/containernetworking/cni/pkg/types"
Expand All @@ -31,11 +32,12 @@ import (
// NetConf is the Cilium specific CNI network configuration
type NetConf struct {
cniTypes.NetConf
MTU int `json:"mtu"`
Args Args `json:"args"`
ENI eniTypes.ENISpec `json:"eni,omitempty"`
IPAM ipamTypes.IPAMSpec `json:"ipam,omitempty"`
EnableDebug bool `json:"enable-debug"`
MTU int `json:"mtu"`
Args Args `json:"args"`
ENI eniTypes.ENISpec `json:"eni,omitempty"`
Azure azureTypes.AzureSpec `json:"azure,omitempty"`
IPAM ipamTypes.IPAMSpec `json:"ipam,omitempty"`
EnableDebug bool `json:"enable-debug"`
}

// NetConfList is a CNI chaining configuration
Expand Down
35 changes: 35 additions & 0 deletions plugins/cilium-cni/types/types_test.go
Expand Up @@ -23,6 +23,7 @@ import (
"testing"

eniTypes "github.com/cilium/cilium/pkg/aws/eni/types"
azureTypes "github.com/cilium/cilium/pkg/azure/types"
"github.com/cilium/cilium/pkg/checker"
ipamTypes "github.com/cilium/cilium/pkg/ipam/types"

Expand Down Expand Up @@ -214,6 +215,40 @@ func (t *CNITypesSuite) TestReadCNIConfENIv2WithPlugins(c *check.C) {
testConfRead(c, confFile1, &netConf1)
}

func (t *CNITypesSuite) TestReadCNIConfAzurev2WithPlugins(c *check.C) {
confFile1 := `
{
"cniVersion":"0.3.1",
"name":"cilium",
"plugins": [
{
"cniVersion":"0.3.1",
"type":"cilium-cni",
"azure": {
"interface-name": "eth1"
},
"ipam": {
"pre-allocate": 5
}
}
]
}
`
netConf1 := NetConf{
NetConf: cnitypes.NetConf{
CNIVersion: "0.3.1",
Type: "cilium-cni",
},
Azure: azureTypes.AzureSpec{
InterfaceName: "eth1",
},
IPAM: ipamTypes.IPAMSpec{
PreAllocate: 5,
},
}
testConfRead(c, confFile1, &netConf1)
}

func (t *CNITypesSuite) TestReadCNIConfError(c *check.C) {
// Try to read errorneous CNI configuration file with MTU provided as
// string instead of int
Expand Down

0 comments on commit 070baff

Please sign in to comment.