Skip to content

Commit 3611142

Browse files
committed
Add GetSubnetByFilter
(cherry picked from commit 6a6b86a)
1 parent 152c874 commit 3611142

File tree

3 files changed

+72
-22
lines changed

3 files changed

+72
-22
lines changed

controllers/openstackcluster_controller.go

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -456,22 +456,23 @@ func reconcileNetworkComponents(scope *scope.Scope, cluster *clusterv1.Cluster,
456456
openStackCluster.Status.Network.Name = networkList[0].Name
457457
openStackCluster.Status.Network.Tags = networkList[0].Tags
458458

459-
subnetOpts := openStackCluster.Spec.Subnet.ToListOpt()
460-
subnetOpts.NetworkID = networkList[0].ID
461-
subnetList, err := networkingService.GetSubnetsByFilter(&subnetOpts)
462-
if err != nil || len(subnetList) == 0 {
463-
handleUpdateOSCError(openStackCluster, errors.Errorf("failed to find subnet: %v", err))
464-
return errors.Errorf("failed to find subnet: %v", err)
465-
}
466-
if len(subnetList) > 1 {
467-
handleUpdateOSCError(openStackCluster, errors.Errorf("failed to find only one subnet (result: %v): %v", subnetList, err))
468-
return errors.Errorf("failed to find only one subnet (result: %v): %v", subnetList, err)
459+
subnet, err := networkingService.GetSubnetByFilter(&openStackCluster.Spec.Subnet)
460+
if err != nil {
461+
err = fmt.Errorf("failed to find subnet: %w", err)
462+
463+
// Set the cluster to failed if subnet filter is invalid
464+
if errors.Is(err, networking.ErrFilterMatch) {
465+
handleUpdateOSCError(openStackCluster, err)
466+
}
467+
468+
return err
469469
}
470+
470471
openStackCluster.Status.Network.Subnet = &infrav1.Subnet{
471-
ID: subnetList[0].ID,
472-
Name: subnetList[0].Name,
473-
CIDR: subnetList[0].CIDR,
474-
Tags: subnetList[0].Tags,
472+
ID: subnet.ID,
473+
Name: subnet.Name,
474+
CIDR: subnet.CIDR,
475+
Tags: subnet.Tags,
475476
}
476477
} else {
477478
err := networkingService.ReconcileNetwork(openStackCluster, clusterName)

pkg/cloud/services/networking/network.go

Lines changed: 54 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,37 @@ import (
2828
infrav1 "sigs.k8s.io/cluster-api-provider-openstack/api/v1alpha6"
2929
"sigs.k8s.io/cluster-api-provider-openstack/pkg/metrics"
3030
"sigs.k8s.io/cluster-api-provider-openstack/pkg/record"
31+
capoerrors "sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/errors"
3132
"sigs.k8s.io/cluster-api-provider-openstack/pkg/utils/names"
3233
)
3334

35+
var (
36+
ErrFilterMatch = fmt.Errorf("filter match error")
37+
ErrMultipleMatches = multipleMatchesError{}
38+
ErrNoMatches = noMatchesError{}
39+
)
40+
41+
type (
42+
multipleMatchesError struct{}
43+
noMatchesError struct{}
44+
)
45+
46+
func (e multipleMatchesError) Error() string {
47+
return "filter matched more than one resource"
48+
}
49+
50+
func (e multipleMatchesError) Is(err error) bool {
51+
return err == ErrFilterMatch
52+
}
53+
54+
func (e noMatchesError) Error() string {
55+
return "filter matched no resources"
56+
}
57+
58+
func (e noMatchesError) Is(err error) bool {
59+
return err == ErrFilterMatch
60+
}
61+
3462
type createOpts struct {
3563
AdminStateUp *bool `json:"admin_state_up,omitempty"`
3664
Name string `json:"name,omitempty"`
@@ -315,11 +343,36 @@ func (s *Service) GetSubnetsByFilter(opts subnets.ListOptsBuilder) ([]subnets.Su
315343
return []subnets.Subnet{}, err
316344
}
317345
if len(subnetList) == 0 {
318-
return nil, fmt.Errorf("no subnets could be found with the filters provided")
346+
return nil, ErrNoMatches
319347
}
320348
return subnetList, nil
321349
}
322350

351+
// GetSubnetByFilter gets a single subnet specified by the given SubnetFilter.
352+
// It returns an ErrFilterMatch if no or multiple subnets are found.
353+
func (s *Service) GetSubnetByFilter(filter *infrav1.SubnetFilter) (*subnets.Subnet, error) {
354+
// If the ID is set, we can just get the subnet by ID.
355+
if filter.ID != "" {
356+
subnet, err := s.client.GetSubnet(filter.ID)
357+
if capoerrors.IsNotFound(err) {
358+
return nil, ErrNoMatches
359+
}
360+
return subnet, err
361+
}
362+
363+
subnets, err := s.GetSubnetsByFilter(filter.ToListOpt())
364+
if err != nil {
365+
return nil, err
366+
}
367+
if len(subnets) == 0 {
368+
return nil, ErrNoMatches
369+
}
370+
if len(subnets) > 1 {
371+
return nil, ErrMultipleMatches
372+
}
373+
return &subnets[0], nil
374+
}
375+
323376
func getSubnetName(clusterName string) string {
324377
return fmt.Sprintf("%s-cluster-%s", networkPrefix, clusterName)
325378
}

pkg/cloud/services/networking/router.go

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -163,15 +163,11 @@ func (s *Service) setRouterExternalIPs(openStackCluster *infrav1.OpenStackCluste
163163
for _, externalRouterIP := range openStackCluster.Spec.ExternalRouterIPs {
164164
subnetID := externalRouterIP.Subnet.UUID
165165
if subnetID == "" {
166-
listOpts := externalRouterIP.Subnet.Filter.ToListOpt()
167-
subnetsByFilter, err := s.GetSubnetsByFilter(&listOpts)
166+
subnet, err := s.GetSubnetByFilter(&externalRouterIP.Subnet.Filter)
168167
if err != nil {
169-
return err
168+
return fmt.Errorf("failed to get subnet for external router: %w", err)
170169
}
171-
if len(subnetsByFilter) != 1 {
172-
return fmt.Errorf("subnetParam didn't exactly match one subnet")
173-
}
174-
subnetID = subnetsByFilter[0].ID
170+
subnetID = subnet.ID
175171
}
176172
updateOpts.GatewayInfo.ExternalFixedIPs = append(updateOpts.GatewayInfo.ExternalFixedIPs, routers.ExternalFixedIP{
177173
IPAddress: externalRouterIP.FixedIP,

0 commit comments

Comments
 (0)