Skip to content

Commit 5f927d2

Browse files
committed
Adopt existing Network in findNetwork when ID is given
1 parent a59626f commit 5f927d2

File tree

2 files changed

+137
-10
lines changed

2 files changed

+137
-10
lines changed

pkg/services/hcloud/network/network.go

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ package network
1919

2020
import (
2121
"context"
22+
"errors"
2223
"fmt"
2324
"net"
2425
"slices"
@@ -106,14 +107,18 @@ func (s *Service) createNetwork(ctx context.Context) (*hcloud.Network, error) {
106107
func (s *Service) createOpts() (hcloud.NetworkCreateOpts, error) {
107108
spec := s.scope.HetznerCluster.Spec.HCloudNetwork
108109

109-
_, network, err := net.ParseCIDR(spec.CIDRBlock)
110+
if spec.CIDRBlock == nil || spec.SubnetCIDRBlock == nil || spec.NetworkZone == nil {
111+
return hcloud.NetworkCreateOpts{}, errors.New("nil CIDRs or NetworkZone given")
112+
}
113+
114+
_, network, err := net.ParseCIDR(*spec.CIDRBlock)
110115
if err != nil {
111-
return hcloud.NetworkCreateOpts{}, fmt.Errorf("invalid network %q: %w", spec.CIDRBlock, err)
116+
return hcloud.NetworkCreateOpts{}, fmt.Errorf("invalid network %q: %w", *spec.CIDRBlock, err)
112117
}
113118

114-
_, subnet, err := net.ParseCIDR(spec.SubnetCIDRBlock)
119+
_, subnet, err := net.ParseCIDR(*spec.SubnetCIDRBlock)
115120
if err != nil {
116-
return hcloud.NetworkCreateOpts{}, fmt.Errorf("invalid network %q: %w", spec.SubnetCIDRBlock, err)
121+
return hcloud.NetworkCreateOpts{}, fmt.Errorf("invalid network %q: %w", *spec.SubnetCIDRBlock, err)
117122
}
118123

119124
return hcloud.NetworkCreateOpts{
@@ -123,7 +128,7 @@ func (s *Service) createOpts() (hcloud.NetworkCreateOpts, error) {
123128
Subnets: []hcloud.NetworkSubnet{
124129
{
125130
IPRange: subnet,
126-
NetworkZone: hcloud.NetworkZone(spec.NetworkZone),
131+
NetworkZone: hcloud.NetworkZone(*spec.NetworkZone),
127132
Type: hcloud.NetworkSubnetTypeCloud,
128133
},
129134
},
@@ -155,6 +160,24 @@ func (s *Service) Delete(ctx context.Context) error {
155160
}
156161

157162
func (s *Service) findNetwork(ctx context.Context) (*hcloud.Network, error) {
163+
// if an ID was provided we want to use the existing Network.
164+
id := s.scope.HetznerCluster.Spec.HCloudNetwork.ID
165+
if id != nil {
166+
network, err := s.scope.HCloudClient.GetNetwork(ctx, *id)
167+
if err != nil {
168+
hcloudutil.HandleRateLimitExceeded(s.scope.HetznerCluster, err, "GetNetwork")
169+
return nil, fmt.Errorf("failed to get network %d: %w", *id, err)
170+
}
171+
172+
if network != nil {
173+
if len(network.Subnets) > 1 {
174+
return nil, fmt.Errorf("multiple subnets not allowed")
175+
}
176+
s.scope.V(1).Info("found network", "id", network.ID, "name", network.Name, "labels", network.Labels)
177+
return network, nil
178+
}
179+
}
180+
158181
opts := hcloud.NetworkListOpts{}
159182
opts.LabelSelector = utils.LabelsToLabelSelector(s.labels())
160183

pkg/services/hcloud/network/network_test.go

Lines changed: 109 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,15 +17,18 @@ limitations under the License.
1717
package network
1818

1919
import (
20+
"context"
2021
"net"
2122
"testing"
2223

2324
"github.com/hetznercloud/hcloud-go/v2/hcloud"
2425
. "github.com/onsi/ginkgo/v2"
2526
. "github.com/onsi/gomega"
27+
"k8s.io/utils/ptr"
2628

2729
infrav1 "github.com/syself/cluster-api-provider-hetzner/api/v1beta1"
2830
"github.com/syself/cluster-api-provider-hetzner/pkg/scope"
31+
fakeclient "github.com/syself/cluster-api-provider-hetzner/pkg/services/hcloud/client/fake"
2932
)
3033

3134
func TestNetwork(t *testing.T) {
@@ -39,9 +42,9 @@ var _ = Describe("Test createOpts", func() {
3942
BeforeEach(func() {
4043
hetznerCluster.Spec.HCloudNetwork = infrav1.HCloudNetworkSpec{
4144
Enabled: true,
42-
CIDRBlock: "10.0.0.0/16",
43-
SubnetCIDRBlock: "10.0.0.0/24",
44-
NetworkZone: "eu-central",
45+
CIDRBlock: ptr.To(infrav1.DefaultCIDRBlock),
46+
SubnetCIDRBlock: ptr.To(infrav1.DefaultSubnetCIDRBlock),
47+
NetworkZone: ptr.To[infrav1.HCloudNetworkZone](infrav1.DefaultNetworkZone),
4548
}
4649
hetznerCluster.Name = "hetzner-cluster"
4750

@@ -73,14 +76,115 @@ var _ = Describe("Test createOpts", func() {
7376
})
7477

7578
It("gives an error with wrong CIDRBlock", func() {
76-
hetznerCluster.Spec.HCloudNetwork.CIDRBlock = "invalid-cidr-block"
79+
hetznerCluster.Spec.HCloudNetwork.CIDRBlock = ptr.To("invalid-cidr-block")
7780
_, err := service.createOpts()
7881
Expect(err).ToNot(BeNil())
7982
})
8083

8184
It("gives an error with wrong SubnetCIDRBlock", func() {
82-
hetznerCluster.Spec.HCloudNetwork.SubnetCIDRBlock = "invalid-cidr-block"
85+
hetznerCluster.Spec.HCloudNetwork.SubnetCIDRBlock = ptr.To("invalid-cidr-block")
8386
_, err := service.createOpts()
8487
Expect(err).ToNot(BeNil())
8588
})
89+
90+
It("gives an error with nil CIDRBlock", func() {
91+
hetznerCluster.Spec.HCloudNetwork.CIDRBlock = nil
92+
_, err := service.createOpts()
93+
Expect(err).ToNot(BeNil())
94+
})
95+
96+
It("gives an error with nil SubnetCIDRBlock", func() {
97+
hetznerCluster.Spec.HCloudNetwork.SubnetCIDRBlock = nil
98+
_, err := service.createOpts()
99+
Expect(err).ToNot(BeNil())
100+
})
101+
102+
It("gives an error with nil NetworkZone", func() {
103+
hetznerCluster.Spec.HCloudNetwork.NetworkZone = nil
104+
_, err := service.createOpts()
105+
Expect(err).ToNot(BeNil())
106+
})
107+
})
108+
109+
var _ = Describe("Test findNetwork", func() {
110+
var hetznerCluster infrav1.HetznerCluster
111+
var service Service
112+
var network *hcloud.Network
113+
client := fakeclient.NewHCloudClientFactory().NewClient("")
114+
115+
BeforeEach(func() {
116+
hetznerCluster.Spec.HCloudNetwork = infrav1.HCloudNetworkSpec{
117+
Enabled: true,
118+
CIDRBlock: ptr.To(infrav1.DefaultCIDRBlock),
119+
SubnetCIDRBlock: ptr.To(infrav1.DefaultSubnetCIDRBlock),
120+
NetworkZone: ptr.To[infrav1.HCloudNetworkZone](infrav1.DefaultNetworkZone),
121+
}
122+
hetznerCluster.Name = "hetzner-cluster"
123+
124+
service = Service{&scope.ClusterScope{HetznerCluster: &hetznerCluster, HCloudClient: client}}
125+
})
126+
AfterEach(func() {
127+
err := client.DeleteNetwork(context.Background(), network)
128+
Expect(err).To(Succeed())
129+
})
130+
It("Gets the Network if ID is set", func() {
131+
hetznerCluster.Spec.HCloudNetwork.ID = ptr.To(int64(1))
132+
133+
var err error
134+
network, err = client.CreateNetwork(context.Background(), hcloud.NetworkCreateOpts{Name: "networkName"})
135+
Expect(err).To(Succeed())
136+
res, err := service.findNetwork(context.Background())
137+
Expect(err).To(BeNil())
138+
Expect(res).To(Equal(network))
139+
})
140+
It("Finds the labeled Network if ID is not set", func() {
141+
var err error
142+
network, err = client.CreateNetwork(context.Background(), hcloud.NetworkCreateOpts{
143+
Name: "networkName",
144+
Labels: map[string]string{
145+
hetznerCluster.ClusterTagKey(): string(infrav1.ResourceLifecycleOwned),
146+
},
147+
})
148+
Expect(err).To(Succeed())
149+
res, err := service.findNetwork(context.Background())
150+
Expect(err).To(BeNil())
151+
Expect(res).To(Equal(network))
152+
})
153+
It("gives an error when there is more than one Network", func() {
154+
var err error
155+
network, err = client.CreateNetwork(context.Background(), hcloud.NetworkCreateOpts{
156+
Name: "networkName",
157+
Labels: map[string]string{
158+
hetznerCluster.ClusterTagKey(): string(infrav1.ResourceLifecycleOwned),
159+
},
160+
})
161+
Expect(err).To(Succeed())
162+
network2, err := client.CreateNetwork(context.Background(), hcloud.NetworkCreateOpts{
163+
Name: "networkName2",
164+
Labels: map[string]string{
165+
hetznerCluster.ClusterTagKey(): string(infrav1.ResourceLifecycleOwned),
166+
},
167+
})
168+
Expect(err).To(Succeed())
169+
res, err := service.findNetwork(context.Background())
170+
Expect(res).To(BeNil())
171+
Expect(err).ToNot(BeNil())
172+
173+
err = client.DeleteNetwork(context.Background(), network2)
174+
Expect(err).To(Succeed())
175+
})
176+
It("gives an error when there is more than one Subnet", func() {
177+
var err error
178+
network, err = client.CreateNetwork(context.Background(), hcloud.NetworkCreateOpts{
179+
Name: "networkName",
180+
Labels: map[string]string{
181+
hetznerCluster.ClusterTagKey(): string(infrav1.ResourceLifecycleOwned),
182+
},
183+
Subnets: make([]hcloud.NetworkSubnet, 2),
184+
})
185+
Expect(err).To(Succeed())
186+
res, err := service.findNetwork(context.Background())
187+
Expect(res).To(BeNil())
188+
Expect(err).ToNot(BeNil())
189+
})
86190
})

0 commit comments

Comments
 (0)