Skip to content

Commit 313c2b7

Browse files
authored
Merge branch 'main' into feature/metrics
2 parents b36976e + 1f644a0 commit 313c2b7

File tree

7 files changed

+308
-13
lines changed

7 files changed

+308
-13
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ jobs:
148148
password: ${{ secrets.DOCKER_PASSWORD }}
149149

150150
- name: Install devbox
151-
uses: jetify-com/devbox-install-action@v0.11.0
151+
uses: jetify-com/devbox-install-action@v0.12.0
152152

153153
- name: Setup CAPL Management Kind Cluster and CAPL Child Cluster For Testing
154154
run: devbox run mgmt-and-capl-cluster

.github/workflows/helm.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ jobs:
3434
check-latest: true
3535

3636
- name: Set up chart-testing
37-
uses: helm/chart-testing-action@v2.6.1
37+
uses: helm/chart-testing-action@v2.7.0
3838

3939
- name: Run chart-testing (lint)
4040
run: ct lint --check-version-increment=false --chart-dirs deploy --target-branch ${{ github.event.repository.default_branch }}
@@ -73,7 +73,7 @@ jobs:
7373
uses: azure/setup-helm@v4
7474

7575
- name: Run chart-releaser
76-
uses: helm/chart-releaser-action@v1.6.0
76+
uses: helm/chart-releaser-action@v1.7.0
7777
env:
7878
CR_TOKEN: "${{ secrets.GITHUB_TOKEN }}"
7979
CR_RELEASE_NAME_TEMPLATE: "helm-{{ .Version }}"

cloud/linode/firewall/firewalls.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,9 @@ func ipsChanged(ips *linodego.NetworkAddresses, rules []linodego.FirewallRule) b
6969
}
7070

7171
if ips.IPv4 != nil {
72+
if len(*ips.IPv4) != len(ruleIPv4s) {
73+
return true
74+
}
7275
for _, ipv4 := range *ips.IPv4 {
7376
if !slices.Contains(ruleIPv4s, ipv4) {
7477
return true
@@ -77,6 +80,9 @@ func ipsChanged(ips *linodego.NetworkAddresses, rules []linodego.FirewallRule) b
7780
}
7881

7982
if ips.IPv6 != nil {
83+
if len(*ips.IPv6) != len(ruleIPv6s) {
84+
return true
85+
}
8086
for _, ipv6 := range *ips.IPv6 {
8187
if !slices.Contains(ruleIPv6s, ipv6) {
8288
return true

cloud/linode/loadbalancers_test.go

Lines changed: 113 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,12 @@ func testCreateNodeBalanceWithBothAllowOrDenyList(t *testing.T, client *linodego
393393
annotations := map[string]string{
394394
annotations.AnnLinodeCloudFirewallACL: `{
395395
"allowList": {
396-
"ipv4": ["2.2.2.2"]
396+
"ipv4": ["2.2.2.2/32"],
397+
"ipv6": ["2001:db8::/128"]
397398
},
398399
"denyList": {
399-
"ipv4": ["2.2.2.2"]
400+
"ipv4": ["2.2.2.2/32"],
401+
"ipv6": ["2001:db8::/128"]
400402
}
401403
}`,
402404
}
@@ -411,29 +413,31 @@ func testCreateNodeBalancerWithAllowList(t *testing.T, client *linodego.Client,
411413
annotations := map[string]string{
412414
annotations.AnnLinodeCloudFirewallACL: `{
413415
"allowList": {
414-
"ipv4": ["2.2.2.2"]
416+
"ipv4": ["2.2.2.2/32"],
417+
"ipv6": ["2001:db8::/128"]
415418
}
416419
}`,
417420
}
418421

419422
err := testCreateNodeBalancer(t, client, f, annotations, nil)
420423
if err != nil {
421-
t.Fatalf("expected a non-nil error, got %v", err)
424+
t.Fatalf("expected a nil error, got %v", err)
422425
}
423426
}
424427

425428
func testCreateNodeBalancerWithDenyList(t *testing.T, client *linodego.Client, f *fakeAPI) {
426429
annotations := map[string]string{
427430
annotations.AnnLinodeCloudFirewallACL: `{
428431
"denyList": {
429-
"ipv4": ["2.2.2.2"]
432+
"ipv4": ["2.2.2.2/32"],
433+
"ipv6": ["2001:db8::/128"]
430434
}
431435
}`,
432436
}
433437

434438
err := testCreateNodeBalancer(t, client, f, annotations, nil)
435439
if err != nil {
436-
t.Fatalf("expected a non-nil error, got %v", err)
440+
t.Fatalf("expected a nil error, got %v", err)
437441
}
438442
}
439443

@@ -1680,7 +1684,7 @@ func testUpdateLoadBalancerUpdateFirewallACL(t *testing.T, client *linodego.Clie
16801684
Annotations: map[string]string{
16811685
annotations.AnnLinodeCloudFirewallACL: `{
16821686
"allowList": {
1683-
"ipv4": ["2.2.2.2"]
1687+
"ipv4": ["2.2.2.2/32", "3.3.3.3/32"]
16841688
}
16851689
}`,
16861690
},
@@ -1744,16 +1748,17 @@ func testUpdateLoadBalancerUpdateFirewallACL(t *testing.T, client *linodego.Clie
17441748

17451749
fwIPs := firewalls[0].Rules.Inbound[0].Addresses.IPv4
17461750
if fwIPs == nil {
1747-
t.Errorf("expected 2.2.2.2, got %v", fwIPs)
1751+
t.Errorf("expected ips, got %v", fwIPs)
17481752
}
17491753

17501754
fmt.Printf("got %v", fwIPs)
17511755

1756+
// Add ipv6 ips in allowList
17521757
svc.ObjectMeta.SetAnnotations(map[string]string{
17531758
annotations.AnnLinodeCloudFirewallACL: `{
17541759
"allowList": {
1755-
"ipv4": ["2.2.2.2"],
1756-
"ipv6": ["dead:beef::/128"]
1760+
"ipv4": ["2.2.2.2/32", "3.3.3.3/32"],
1761+
"ipv6": ["dead:beef::/128", "dead:bee::/128"]
17571762
}
17581763
}`,
17591764
})
@@ -1782,6 +1787,98 @@ func testUpdateLoadBalancerUpdateFirewallACL(t *testing.T, client *linodego.Clie
17821787
t.Errorf("expected non nil IPv4, got %v", fwIPs)
17831788
}
17841789

1790+
if len(*fwIPs) != 2 {
1791+
t.Errorf("expected two IPv4 ips, got %v", fwIPs)
1792+
}
1793+
1794+
if firewallsNew[0].Rules.Inbound[0].Addresses.IPv6 == nil {
1795+
t.Errorf("expected non nil IPv6, got %v", firewallsNew[0].Rules.Inbound[0].Addresses.IPv6)
1796+
}
1797+
1798+
if len(*firewallsNew[0].Rules.Inbound[0].Addresses.IPv6) != 2 {
1799+
t.Errorf("expected two IPv6 ips, got %v", firewallsNew[0].Rules.Inbound[0].Addresses.IPv6)
1800+
}
1801+
1802+
// Update ips in allowList
1803+
svc.ObjectMeta.SetAnnotations(map[string]string{
1804+
annotations.AnnLinodeCloudFirewallACL: `{
1805+
"allowList": {
1806+
"ipv4": ["2.2.2.1/32", "3.3.3.3/32"],
1807+
"ipv6": ["dead::/128", "dead:bee::/128"]
1808+
}
1809+
}`,
1810+
})
1811+
1812+
err = lb.UpdateLoadBalancer(context.TODO(), "linodelb", svc, nodes)
1813+
if err != nil {
1814+
t.Errorf("UpdateLoadBalancer returned an error: %s", err)
1815+
}
1816+
1817+
nbUpdated, err = lb.getNodeBalancerByStatus(context.TODO(), svc)
1818+
if err != nil {
1819+
t.Fatalf("failed to get NodeBalancer via status: %s", err)
1820+
}
1821+
1822+
firewallsNew, err = lb.client.ListNodeBalancerFirewalls(context.TODO(), nbUpdated.ID, &linodego.ListOptions{})
1823+
if err != nil {
1824+
t.Fatalf("failed to List Firewalls %s", err)
1825+
}
1826+
1827+
if len(firewallsNew) == 0 {
1828+
t.Fatalf("No attached firewalls found")
1829+
}
1830+
1831+
fwIPs = firewallsNew[0].Rules.Inbound[0].Addresses.IPv4
1832+
if fwIPs == nil {
1833+
t.Errorf("expected non nil IPv4, got %v", fwIPs)
1834+
}
1835+
1836+
if len(*fwIPs) != 2 {
1837+
t.Errorf("expected two IPv4 ips, got %v", fwIPs)
1838+
}
1839+
1840+
if firewallsNew[0].Rules.Inbound[0].Addresses.IPv6 == nil {
1841+
t.Errorf("expected non nil IPv6, got %v", firewallsNew[0].Rules.Inbound[0].Addresses.IPv6)
1842+
}
1843+
1844+
if len(*firewallsNew[0].Rules.Inbound[0].Addresses.IPv6) != 2 {
1845+
t.Errorf("expected two IPv6 ips, got %v", firewallsNew[0].Rules.Inbound[0].Addresses.IPv6)
1846+
}
1847+
1848+
// remove one ipv4 and one ipv6 ip from allowList
1849+
svc.ObjectMeta.SetAnnotations(map[string]string{
1850+
annotations.AnnLinodeCloudFirewallACL: `{
1851+
"allowList": {
1852+
"ipv4": ["3.3.3.3/32"],
1853+
"ipv6": ["dead:beef::/128"]
1854+
}
1855+
}`,
1856+
})
1857+
1858+
err = lb.UpdateLoadBalancer(context.TODO(), "linodelb", svc, nodes)
1859+
if err != nil {
1860+
t.Errorf("UpdateLoadBalancer returned an error: %s", err)
1861+
}
1862+
1863+
nbUpdated, err = lb.getNodeBalancerByStatus(context.TODO(), svc)
1864+
if err != nil {
1865+
t.Fatalf("failed to get NodeBalancer via status: %s", err)
1866+
}
1867+
1868+
firewallsNew, err = lb.client.ListNodeBalancerFirewalls(context.TODO(), nbUpdated.ID, &linodego.ListOptions{})
1869+
if err != nil {
1870+
t.Fatalf("failed to List Firewalls %s", err)
1871+
}
1872+
1873+
if len(firewallsNew) == 0 {
1874+
t.Fatalf("No attached firewalls found")
1875+
}
1876+
1877+
fwIPs = firewallsNew[0].Rules.Inbound[0].Addresses.IPv4
1878+
if fwIPs == nil {
1879+
t.Errorf("expected non nil IPv4, got %v", fwIPs)
1880+
}
1881+
17851882
if len(*fwIPs) != 1 {
17861883
t.Errorf("expected one IPv4, got %v", fwIPs)
17871884
}
@@ -1793,6 +1890,12 @@ func testUpdateLoadBalancerUpdateFirewallACL(t *testing.T, client *linodego.Clie
17931890
if len(*firewallsNew[0].Rules.Inbound[0].Addresses.IPv6) != 1 {
17941891
t.Errorf("expected one IPv6, got %v", firewallsNew[0].Rules.Inbound[0].Addresses.IPv6)
17951892
}
1893+
1894+
// Run update with same ACL
1895+
err = lb.UpdateLoadBalancer(context.TODO(), "linodelb", svc, nodes)
1896+
if err != nil {
1897+
t.Errorf("UpdateLoadBalancer returned an error: %s", err)
1898+
}
17961899
}
17971900

17981901
func testUpdateLoadBalancerUpdateFirewall(t *testing.T, client *linodego.Client, fakeAPI *fakeAPI) {
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/kyverno/chainsaw/main/.schemas/json/test-chainsaw-v1alpha1.json
2+
apiVersion: chainsaw.kyverno.io/v1alpha1
3+
kind: Test
4+
metadata:
5+
name: lb-fw-update-acl
6+
spec:
7+
namespace: "lb-fw-update-acl"
8+
steps:
9+
- name: Check if CCM is deployed
10+
try:
11+
- assert:
12+
file: ../assert-ccm-resources.yaml
13+
- name: Create pods and services
14+
try:
15+
- apply:
16+
file: create-pods-services.yaml
17+
catch:
18+
- describe:
19+
apiVersion: v1
20+
kind: Pod
21+
- describe:
22+
apiVersion: v1
23+
kind: Service
24+
- name: Check that loadbalancer ip is assigned
25+
try:
26+
- assert:
27+
resource:
28+
apiVersion: v1
29+
kind: Service
30+
metadata:
31+
name: svc-test
32+
status:
33+
(loadBalancer.ingress[0].ip != null): true
34+
- name: Fetch Nodebalancer ID, make sure it has firewall attached
35+
try:
36+
- script:
37+
content: |
38+
set -e
39+
40+
for i in {1..10}; do
41+
nbid=$(KUBECONFIG=$KUBECONFIG NAMESPACE=$NAMESPACE LINODE_TOKEN=$LINODE_TOKEN ../scripts/get-nb-id.sh)
42+
43+
fw=$(curl -s --request GET \
44+
-H "Authorization: Bearer $LINODE_TOKEN" \
45+
-H "Content-Type: application/json" \
46+
-H "accept: application/json" \
47+
"https://api.linode.com/v4/nodebalancers/${nbid}/firewalls" || true)
48+
49+
fwCount=$(echo $fw | jq '.data | length')
50+
ips=$(echo $fw | jq '.data[].rules.inbound[].addresses.ipv4[]')
51+
if [[ $fwCount -eq 1 && -n $ips && $ips == *"7.7.7.7/32"* ]]; then
52+
echo "firewall attached and rule has specified ip"
53+
break
54+
fi
55+
sleep 10
56+
done
57+
check:
58+
($error == null): true
59+
(contains($stdout, 'firewall attached and rule has specified ip')): true
60+
- name: Update service with new ACL
61+
try:
62+
- apply:
63+
file: update-service.yaml
64+
catch:
65+
- describe:
66+
apiVersion: v1
67+
kind: Service
68+
- name: Fetch firewall ID and check rules are updated
69+
try:
70+
- script:
71+
content: |
72+
set -e
73+
74+
for i in {1..10}; do
75+
nbid=$(KUBECONFIG=$KUBECONFIG NAMESPACE=$NAMESPACE LINODE_TOKEN=$LINODE_TOKEN ../scripts/get-nb-id.sh)
76+
77+
fw=$(curl -s --request GET \
78+
-H "Authorization: Bearer $LINODE_TOKEN" \
79+
-H "Content-Type: application/json" \
80+
-H "accept: application/json" \
81+
"https://api.linode.com/v4/nodebalancers/${nbid}/firewalls" || true)
82+
83+
fwCount=$(echo $fw | jq -r '.data | length')
84+
ips=$(echo $fw | jq -r '.data[].rules.inbound[].addresses.ipv4[]')
85+
if [[ $fwCount -eq 1 && -n $ips && ! $ips == *"7.7.7.7/32"* ]]; then
86+
echo "firewall attached and rule updated"
87+
break
88+
fi
89+
sleep 10
90+
done
91+
check:
92+
($error == null): true
93+
(contains($stdout, 'firewall attached and rule updated')): true

0 commit comments

Comments
 (0)