Skip to content

Commit 0fbb922

Browse files
authored
Merge pull request #167 from flawedmatrix/cluster-paused-detection
🐛 Update cluster paused detection
2 parents b1522e9 + 4ca0d89 commit 0fbb922

File tree

2 files changed

+214
-49
lines changed

2 files changed

+214
-49
lines changed

internal/controllers/ipaddressclaim.go

+4-3
Original file line numberDiff line numberDiff line change
@@ -93,10 +93,11 @@ func (r *IPAddressClaimReconciler) SetupWithManager(ctx context.Context, mgr ctr
9393
UpdateFunc: func(e event.UpdateEvent) bool {
9494
oldCluster := e.ObjectOld.(*clusterv1.Cluster)
9595
newCluster := e.ObjectNew.(*clusterv1.Cluster)
96-
return oldCluster.Spec.Paused && !newCluster.Spec.Paused
96+
return annotations.IsPaused(oldCluster, oldCluster) && !annotations.IsPaused(newCluster, newCluster)
9797
},
9898
CreateFunc: func(e event.CreateEvent) bool {
99-
return !annotations.HasPaused(e.Object)
99+
cluster := e.Object.(*clusterv1.Cluster)
100+
return !annotations.IsPaused(cluster, cluster)
100101
},
101102
}),
102103
).
@@ -188,7 +189,7 @@ func (r *IPAddressClaimReconciler) Reconcile(ctx context.Context, req ctrl.Reque
188189
return ctrl.Result{}, err
189190
}
190191

191-
if annotations.IsPaused(cluster, claim) {
192+
if annotations.IsPaused(cluster, cluster) {
192193
log.Info("IPAddressClaim linked to a cluster that is paused, skipping reconciliation")
193194
return ctrl.Result{}, nil
194195
}

internal/controllers/ipaddressclaim_test.go

+210-46
Original file line numberDiff line numberDiff line change
@@ -1641,9 +1641,10 @@ var _ = Describe("IPAddressClaimReconciler", func() {
16411641
})
16421642
})
16431643

1644-
Context("When the cluster is paused and the ipaddressclaim has the cluster-name label", func() {
1644+
Context("When the cluster is spec.paused true and the ipaddressclaim has the cluster-name label", func() {
16451645
const (
1646-
poolName = "test-pool"
1646+
clusterName = "test-cluster"
1647+
poolName = "test-pool"
16471648
)
16481649

16491650
var (
@@ -1667,33 +1668,109 @@ var _ = Describe("IPAddressClaimReconciler", func() {
16671668
})
16681669

16691670
Context("When the cluster can be retrieved", func() {
1670-
BeforeEach(func() {
1671+
AfterEach(func() {
1672+
deleteClaim("test", namespace)
1673+
deleteCluster(clusterName, namespace)
1674+
deleteNamespacedPool(poolName, namespace)
1675+
})
1676+
1677+
It("does not allocate an ipaddress upon creating a cluster when the cluster has paused annotation", func() {
1678+
claim := ipamv1.IPAddressClaim{
1679+
ObjectMeta: metav1.ObjectMeta{
1680+
Name: "test",
1681+
Namespace: namespace,
1682+
Labels: map[string]string{
1683+
clusterv1.ClusterNameLabel: clusterName,
1684+
},
1685+
},
1686+
Spec: ipamv1.IPAddressClaimSpec{
1687+
PoolRef: corev1.TypedLocalObjectReference{
1688+
APIGroup: pointer.String("ipam.cluster.x-k8s.io"),
1689+
Kind: "InClusterIPPool",
1690+
Name: poolName,
1691+
},
1692+
},
1693+
}
1694+
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1695+
Eventually(Get(&claim)).Should(Succeed())
1696+
16711697
cluster = clusterv1.Cluster{
16721698
ObjectMeta: metav1.ObjectMeta{
1673-
GenerateName: "test-cluster",
1674-
Namespace: namespace,
1699+
Name: clusterName,
1700+
Namespace: namespace,
1701+
Annotations: map[string]string{
1702+
clusterv1.PausedAnnotation: "",
1703+
},
1704+
},
1705+
}
1706+
Expect(k8sClient.Create(context.Background(), &cluster)).To(Succeed())
1707+
Eventually(Get(&cluster)).Should(Succeed())
1708+
1709+
addresses := ipamv1.IPAddressList{}
1710+
Consistently(ObjectList(&addresses)).
1711+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1712+
HaveField("Items", HaveLen(0)))
1713+
})
1714+
1715+
It("does not allocate an ipaddress upon creating a cluster when the cluster has spec.Paused", func() {
1716+
claim := ipamv1.IPAddressClaim{
1717+
ObjectMeta: metav1.ObjectMeta{
1718+
Name: "test",
1719+
Namespace: namespace,
1720+
Labels: map[string]string{
1721+
clusterv1.ClusterNameLabel: clusterName,
1722+
},
1723+
},
1724+
Spec: ipamv1.IPAddressClaimSpec{
1725+
PoolRef: corev1.TypedLocalObjectReference{
1726+
APIGroup: pointer.String("ipam.cluster.x-k8s.io"),
1727+
Kind: "InClusterIPPool",
1728+
Name: poolName,
1729+
},
1730+
},
1731+
}
1732+
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1733+
Eventually(Get(&claim)).Should(Succeed())
1734+
1735+
cluster = clusterv1.Cluster{
1736+
ObjectMeta: metav1.ObjectMeta{
1737+
Name: clusterName,
1738+
Namespace: namespace,
16751739
},
16761740
Spec: clusterv1.ClusterSpec{
16771741
Paused: true,
16781742
},
16791743
}
1744+
16801745
Expect(k8sClient.Create(context.Background(), &cluster)).To(Succeed())
16811746
Eventually(Get(&cluster)).Should(Succeed())
1682-
})
16831747

1684-
AfterEach(func() {
1685-
deleteClaim("test", namespace)
1686-
deleteCluster(cluster.GetName(), namespace)
1687-
deleteNamespacedPool(poolName, namespace)
1748+
addresses := ipamv1.IPAddressList{}
1749+
Consistently(ObjectList(&addresses)).
1750+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1751+
HaveField("Items", HaveLen(0)))
16881752
})
16891753

1690-
It("does not allocate an ipaddress for the claim until the cluster is unpaused", func() {
1754+
It("does not allocate an ipaddress upon updating a cluster when the cluster has spec.paused", func() {
1755+
cluster = clusterv1.Cluster{
1756+
ObjectMeta: metav1.ObjectMeta{
1757+
Name: clusterName,
1758+
Namespace: namespace,
1759+
},
1760+
Spec: clusterv1.ClusterSpec{
1761+
Paused: true,
1762+
},
1763+
}
1764+
1765+
Expect(k8sClient.Create(context.Background(), &cluster)).To(Succeed())
1766+
Eventually(Get(&cluster)).Should(Succeed())
1767+
16911768
claim := ipamv1.IPAddressClaim{
16921769
ObjectMeta: metav1.ObjectMeta{
16931770
Name: "test",
16941771
Namespace: namespace,
16951772
Labels: map[string]string{
1696-
clusterv1.ClusterNameLabel: cluster.GetName(),
1773+
clusterv1.ClusterNameLabel: clusterName,
16971774
},
16981775
},
16991776
Spec: ipamv1.IPAddressClaimSpec{
@@ -1707,64 +1784,151 @@ var _ = Describe("IPAddressClaimReconciler", func() {
17071784
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
17081785
Eventually(Get(&claim)).Should(Succeed())
17091786

1787+
// update the cluster
1788+
cluster.Annotations = map[string]string{"superficial": "change"}
1789+
Expect(k8sClient.Update(context.Background(), &cluster)).To(Succeed())
1790+
17101791
addresses := ipamv1.IPAddressList{}
17111792
Consistently(ObjectList(&addresses)).
17121793
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
17131794
HaveField("Items", HaveLen(0)))
1795+
})
17141796

1715-
// Unpause the cluster
1716-
cluster.Spec.Paused = false
1717-
Expect(k8sClient.Update(context.Background(), &cluster)).To(Succeed())
1797+
It("does not allocate an ipaddress upon updating a cluster when the cluster has paused annotation", func() {
1798+
cluster = clusterv1.Cluster{
1799+
ObjectMeta: metav1.ObjectMeta{
1800+
Name: clusterName,
1801+
Namespace: namespace,
1802+
Annotations: map[string]string{
1803+
clusterv1.PausedAnnotation: "",
1804+
},
1805+
},
1806+
}
17181807

1719-
expectedIPAddress := ipamv1.IPAddress{
1808+
Expect(k8sClient.Create(context.Background(), &cluster)).To(Succeed())
1809+
Eventually(Get(&cluster)).Should(Succeed())
1810+
1811+
claim := ipamv1.IPAddressClaim{
17201812
ObjectMeta: metav1.ObjectMeta{
1721-
Name: "test",
1722-
Namespace: namespace,
1723-
Finalizers: []string{ProtectAddressFinalizer},
1724-
OwnerReferences: []metav1.OwnerReference{
1725-
{
1726-
APIVersion: "ipam.cluster.x-k8s.io/v1alpha1",
1727-
BlockOwnerDeletion: pointer.Bool(true),
1728-
Controller: pointer.Bool(true),
1729-
Kind: "IPAddressClaim",
1730-
Name: "test",
1731-
},
1732-
{
1733-
APIVersion: "ipam.cluster.x-k8s.io/v1alpha2",
1734-
BlockOwnerDeletion: pointer.Bool(true),
1735-
Controller: pointer.Bool(false),
1736-
Kind: "InClusterIPPool",
1737-
Name: poolName,
1738-
},
1813+
Name: "test",
1814+
Namespace: namespace,
1815+
Labels: map[string]string{
1816+
clusterv1.ClusterNameLabel: clusterName,
17391817
},
17401818
},
1741-
Spec: ipamv1.IPAddressSpec{
1742-
ClaimRef: corev1.LocalObjectReference{
1743-
Name: "test",
1819+
Spec: ipamv1.IPAddressClaimSpec{
1820+
PoolRef: corev1.TypedLocalObjectReference{
1821+
APIGroup: pointer.String("ipam.cluster.x-k8s.io"),
1822+
Kind: "InClusterIPPool",
1823+
Name: poolName,
17441824
},
1825+
},
1826+
}
1827+
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1828+
Eventually(Get(&claim)).Should(Succeed())
1829+
1830+
// update the cluster
1831+
cluster.Annotations["superficial"] = "change"
1832+
Expect(k8sClient.Update(context.Background(), &cluster)).To(Succeed())
1833+
1834+
addresses := ipamv1.IPAddressList{}
1835+
Consistently(ObjectList(&addresses)).
1836+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1837+
HaveField("Items", HaveLen(0)))
1838+
})
1839+
1840+
It("allocates an ipaddress upon updating a cluster when removing spec.paused", func() {
1841+
cluster = clusterv1.Cluster{
1842+
ObjectMeta: metav1.ObjectMeta{
1843+
Name: clusterName,
1844+
Namespace: namespace,
1845+
},
1846+
Spec: clusterv1.ClusterSpec{
1847+
Paused: true,
1848+
},
1849+
}
1850+
1851+
Expect(k8sClient.Create(context.Background(), &cluster)).To(Succeed())
1852+
Eventually(Get(&cluster)).Should(Succeed())
1853+
1854+
claim := ipamv1.IPAddressClaim{
1855+
ObjectMeta: metav1.ObjectMeta{
1856+
Name: "test",
1857+
Namespace: namespace,
1858+
Labels: map[string]string{
1859+
clusterv1.ClusterNameLabel: clusterName,
1860+
},
1861+
},
1862+
Spec: ipamv1.IPAddressClaimSpec{
17451863
PoolRef: corev1.TypedLocalObjectReference{
17461864
APIGroup: pointer.String("ipam.cluster.x-k8s.io"),
17471865
Kind: "InClusterIPPool",
17481866
Name: poolName,
17491867
},
1750-
Address: "10.0.0.1",
1751-
Prefix: 24,
1752-
Gateway: "10.0.0.2",
17531868
},
17541869
}
1870+
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1871+
Eventually(Get(&claim)).Should(Succeed())
17551872

1756-
address := ipamv1.IPAddress{
1873+
addresses := ipamv1.IPAddressList{}
1874+
Consistently(ObjectList(&addresses)).
1875+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1876+
HaveField("Items", HaveLen(0)))
1877+
1878+
// update the cluster
1879+
cluster.Spec.Paused = false
1880+
Expect(k8sClient.Update(context.Background(), &cluster)).To(Succeed())
1881+
1882+
Eventually(ObjectList(&addresses)).
1883+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1884+
HaveField("Items", HaveLen(1)))
1885+
})
1886+
1887+
It("allocates an ipaddress upon updating a cluster when removing the paused annotation", func() {
1888+
cluster = clusterv1.Cluster{
1889+
ObjectMeta: metav1.ObjectMeta{
1890+
Name: clusterName,
1891+
Namespace: namespace,
1892+
Annotations: map[string]string{
1893+
clusterv1.PausedAnnotation: "",
1894+
},
1895+
},
1896+
}
1897+
1898+
Expect(k8sClient.Create(context.Background(), &cluster)).To(Succeed())
1899+
Eventually(Get(&cluster)).Should(Succeed())
1900+
1901+
claim := ipamv1.IPAddressClaim{
17571902
ObjectMeta: metav1.ObjectMeta{
17581903
Name: "test",
17591904
Namespace: namespace,
1905+
Labels: map[string]string{
1906+
clusterv1.ClusterNameLabel: clusterName,
1907+
},
1908+
},
1909+
Spec: ipamv1.IPAddressClaimSpec{
1910+
PoolRef: corev1.TypedLocalObjectReference{
1911+
APIGroup: pointer.String("ipam.cluster.x-k8s.io"),
1912+
Kind: "InClusterIPPool",
1913+
Name: poolName,
1914+
},
17601915
},
1761-
Spec: ipamv1.IPAddressSpec{},
17621916
}
1917+
Expect(k8sClient.Create(context.Background(), &claim)).To(Succeed())
1918+
Eventually(Get(&claim)).Should(Succeed())
17631919

1764-
Eventually(Object(&address)).
1765-
WithTimeout(time.Second).WithPolling(100 * time.Millisecond).Should(
1766-
EqualObject(&expectedIPAddress, IgnoreAutogeneratedMetadata, IgnoreUIDsOnIPAddress),
1767-
)
1920+
addresses := ipamv1.IPAddressList{}
1921+
Consistently(ObjectList(&addresses)).
1922+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1923+
HaveField("Items", HaveLen(0)))
1924+
1925+
// update the cluster
1926+
delete(cluster.Annotations, clusterv1.PausedAnnotation)
1927+
Expect(k8sClient.Update(context.Background(), &cluster)).To(Succeed())
1928+
1929+
Eventually(ObjectList(&addresses)).
1930+
WithTimeout(5 * time.Second).WithPolling(100 * time.Millisecond).Should(
1931+
HaveField("Items", HaveLen(1)))
17681932
})
17691933
})
17701934

0 commit comments

Comments
 (0)