Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP]SKS-1825: Use the default IPPool as the global IPPool #37

Merged
merged 3 commits into from
Apr 9, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions controllers/elfmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,16 @@ func (r *ElfMachineReconciler) reconcileDeviceIPAddress(ctx *context.MachineCont
return ctrl.Result{}, nil
}

// getIPPool returns the specified IPPool.
//
// getIPPool selects IPPool according to the following priorities:
// (1) Without ip-pool-name
// 1. select IPPool with `is-default`` label from elfMachine.Namespace
// 2. select IPPool with `is-default` label from default namespace
// (2) With ip-pool-name(from AddressesFromPools or ElfMachineTemplate)
// 1. select IPPool using the specified ip-pool-name and ip-pool-namespace
// 2. select the IPPool named ip-pool-name in the default namespace

func (r *ElfMachineReconciler) getIPPool(ctx *context.MachineContext, device capev1.NetworkDeviceSpec) (ipam.IPPool, error) {
poolMatchLabels := make(map[string]string)
// Prefer IPPool of device. Only Metal3 IPPool is supported now.
Expand Down
2 changes: 2 additions & 0 deletions controllers/elfmachine_controller_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -226,9 +226,11 @@ var _ = Describe("ElfMachineReconciler", func() {

It("should wait for IP when IPClaim without IP", func() {
ctrlutil.AddFinalizer(elfMachine, MachineStaticIPFinalizer)
metal3IPPool.Namespace = ipam.DefaultIPPoolNamespace
metal3IPPool.Labels = map[string]string{
ipam.ClusterIPPoolGroupKey: "ip-pool-group",
ipam.ClusterNetworkNameKey: "ip-pool-vm-network",
ipam.DefaultIPPoolKey: "true",
}
elfMachineTemplate.Labels = metal3IPPool.Labels
metal3IPClaim, metal3IPAddress = fake.NewMetal3IPObjects(metal3IPPool, ipamutil.GetFormattedClaimName(elfMachine.Namespace, elfMachine.Name, 0))
Expand Down
2 changes: 1 addition & 1 deletion pkg/ipam/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ const (

// Default IPPool.
const (
DefaultIPPoolNamespace = "cape-system"
DefaultIPPoolNamespace = "default"
DefaultIPPoolKey = "ippool.cluster.x-k8s.io/is-default"
)
78 changes: 50 additions & 28 deletions pkg/ipam/metal3io/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,26 +130,28 @@ func (m *Metal3IPAM) ReleaseIPs(ctx goctx.Context, owner metav1.Object, pool ipa

func (m *Metal3IPAM) GetAvailableIPPool(ctx goctx.Context, poolMatchLabels map[string]string, clusterMeta metav1.ObjectMeta) (ipam.IPPool, error) {
poolNamespace := getIPPoolNamespace(poolMatchLabels, clusterMeta)
poolName := poolMatchLabels[ipam.ClusterIPPoolNameKey]

// if the specific ip-pool name is provided use that to get the ip-pool
var ipPool ipamv1.IPPool
if poolName, ok := poolMatchLabels[ipam.ClusterIPPoolNameKey]; ok && poolName != "" {
if err := m.Get(ctx, apitypes.NamespacedName{
Namespace: poolNamespace,
Name: poolName,
}, &ipPool); err != nil {
if apierrors.IsNotFound(err) {
return nil, nil
}

return nil, errors.Wrapf(err, "failed to get IPPool %s/%s", poolNamespace, poolName)
}

return toIPPool(ipPool), nil
// 1. If the specific ip-pool name is provided use that to get the ip-pool.
if poolName != "" {
return m.getIPPoolByName(ctx, poolNamespace, poolName)
}

matchLabels := map[string]string{}
// 2. Otherwise use default ip-pool

ipPoolList := &ipamv1.IPPoolList{}
if err := m.List(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

建议这里改成一个func:getIPPoolByLabels()

ctx,
ipPoolList,
client.InNamespace(clusterMeta.Namespace),
client.MatchingLabels(map[string]string{ipam.DefaultIPPoolKey: "true"})); err != nil {
return nil, err
}
if len(ipPoolList.Items) > 0 {
return toIPPool(ipPoolList.Items[0]), nil
}

matchLabels := map[string]string{ipam.DefaultIPPoolKey: "true"}
// use labels 'ip-pool-group' & 'network-name' to select the ip-pool
if label, ok := poolMatchLabels[ipam.ClusterIPPoolGroupKey]; ok && label != "" {
matchLabels[ipam.ClusterIPPoolGroupKey] = label
Expand All @@ -158,30 +160,50 @@ func (m *Metal3IPAM) GetAvailableIPPool(ctx goctx.Context, poolMatchLabels map[s
matchLabels[ipam.ClusterNetworkNameKey] = label
}

// use default ip-pool
if len(matchLabels) == 0 {
poolNamespace = ipam.DefaultIPPoolNamespace
matchLabels[ipam.DefaultIPPoolKey] = "true"
}

ipPoolList := &ipamv1.IPPoolList{}
ipPoolList = &ipamv1.IPPoolList{}
if err := m.List(
ctx,
ipPoolList,
client.InNamespace(poolNamespace),
client.InNamespace(ipam.DefaultIPPoolNamespace),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

如果DefaultIPPoolNamespace和clusterMeta.Namespace 一样,这个if 是不是就不用执行了?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

后面还有 ClusterIPPoolGroupKey & ClusterNetworkNameKey,这两个没有用到,可以考虑删了。

client.MatchingLabels(matchLabels)); err != nil {
return nil, err
}

if len(ipPoolList.Items) == 0 {
m.logger.Info("failed to get a matching IPPool")
return nil, nil
}
ipPool = ipPoolList.Items[0]

m.logger.Info(fmt.Sprintf("IPPool %s is available", ipPool.Name))
return toIPPool(ipPoolList.Items[0]), nil
}

// getIPPoolByName returns the IPPool with the specified name.
//
// If IPPool is not found in the specified namespace, will try to find from the
// default namespace.
func (m *Metal3IPAM) getIPPoolByName(ctx goctx.Context, poolNamespace, poolName string) (ipam.IPPool, error) {
var ipPool ipamv1.IPPool
err := m.Get(ctx, apitypes.NamespacedName{
Namespace: poolNamespace,
Name: poolName,
}, &ipPool)
if err == nil {
return toIPPool(ipPool), nil
} else if !apierrors.IsNotFound(err) {
return nil, errors.Wrapf(err, "failed to get IPPool %s/%s", poolNamespace, poolName)
}

// Try the ip-pool default namespace.
err = m.Get(ctx, apitypes.NamespacedName{
Namespace: ipam.DefaultIPPoolNamespace,
Name: poolName,
}, &ipPool)
if err == nil {
return toIPPool(ipPool), nil
} else if apierrors.IsNotFound(err) {
return nil, nil
}

return toIPPool(ipPool), nil
return nil, errors.Wrapf(err, "failed to get IPPool %s/%s", poolNamespace, poolName)
}

func (m *Metal3IPAM) getIPClaim(ctx goctx.Context, pool ipam.IPPool, claimName string) (*ipamv1.IPClaim, error) {
Expand Down
Loading