Skip to content

Commit 305c79a

Browse files
authored
fix: nil pointer deference in subnet_reconciler (#449)
1 parent 286d666 commit 305c79a

File tree

2 files changed

+168
-8
lines changed

2 files changed

+168
-8
lines changed

cloud/scope/subnet_reconciler.go

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,12 @@ import (
2020
"context"
2121
"fmt"
2222
"net"
23+
"slices"
2324
"strings"
2425

2526
infrastructurev1beta2 "github.com/oracle/cluster-api-provider-oci/api/v1beta2"
2627
"github.com/oracle/cluster-api-provider-oci/cloud/ociutil"
28+
"github.com/oracle/cluster-api-provider-oci/cloud/ociutil/ptr"
2729
"github.com/oracle/oci-go-sdk/v65/common"
2830
"github.com/oracle/oci-go-sdk/v65/core"
2931
"github.com/pkg/errors"
@@ -297,19 +299,18 @@ func (s *ClusterScope) GetSubnetsSpec() []*infrastructurev1beta2.Subnet {
297299
}
298300

299301
func (s *ClusterScope) IsSubnetsEqual(actual *core.Subnet, desired infrastructurev1beta2.Subnet) bool {
300-
if desired.Name != *actual.DisplayName {
302+
if desired.Name != ptr.ToString(actual.DisplayName) {
301303
return false
302304
}
303-
if desired.CIDR != *actual.CidrBlock {
305+
if desired.CIDR != ptr.ToString(actual.CidrBlock) {
304306
return false
305307
}
306-
if desired.SecurityList != nil && desired.SecurityList.ID != nil {
307-
for _, securityListId := range actual.SecurityListIds {
308-
if *desired.SecurityList.ID == securityListId {
309-
return true
310-
}
308+
if desired.SecurityList != nil {
309+
if desired.SecurityList.ID == nil {
310+
return false
311311
}
312-
return false
312+
313+
return slices.Contains(actual.SecurityListIds, ptr.ToString(desired.SecurityList.ID))
313314
}
314315
return true
315316
}

cloud/scope/subnet_reconciler_test.go

Lines changed: 159 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -911,3 +911,162 @@ func isSubnetsEqual(desiredSubnets []*infrastructurev1beta2.Subnet, actualSubnet
911911
}
912912
return true
913913
}
914+
915+
func TestClusterScope_IsSubnetsEqual(t *testing.T) {
916+
s := &ClusterScope{}
917+
secID := common.String("secid")
918+
919+
tests := []struct {
920+
name string
921+
actual core.Subnet
922+
desired infrastructurev1beta2.Subnet
923+
want bool
924+
}{
925+
{
926+
name: "equal without security list",
927+
actual: core.Subnet{
928+
DisplayName: common.String("name"),
929+
CidrBlock: common.String("10.0.0.0/24"),
930+
},
931+
desired: infrastructurev1beta2.Subnet{
932+
Name: "name",
933+
CIDR: "10.0.0.0/24",
934+
},
935+
want: true,
936+
},
937+
{
938+
name: "actual nil DisplayName",
939+
actual: core.Subnet{
940+
DisplayName: nil,
941+
CidrBlock: common.String("10.0.0.0/24"),
942+
},
943+
desired: infrastructurev1beta2.Subnet{
944+
Name: "",
945+
CIDR: "10.0.0.0/24",
946+
},
947+
want: true,
948+
},
949+
{
950+
name: "actual nil CidrBlock",
951+
actual: core.Subnet{
952+
DisplayName: common.String("name"),
953+
CidrBlock: nil,
954+
},
955+
desired: infrastructurev1beta2.Subnet{
956+
Name: "name",
957+
CIDR: "",
958+
},
959+
want: true,
960+
},
961+
{
962+
name: "name mismatch",
963+
actual: core.Subnet{
964+
DisplayName: common.String("other"),
965+
CidrBlock: common.String("10.0.0.0/24"),
966+
},
967+
desired: infrastructurev1beta2.Subnet{
968+
Name: "name",
969+
CIDR: "10.0.0.0/24",
970+
},
971+
want: false,
972+
},
973+
{
974+
name: "cidr mismatch",
975+
actual: core.Subnet{
976+
DisplayName: common.String("name"),
977+
CidrBlock: common.String("10.0.1.0/24"),
978+
},
979+
desired: infrastructurev1beta2.Subnet{
980+
Name: "name",
981+
CIDR: "10.0.0.0/24",
982+
},
983+
want: false,
984+
},
985+
{
986+
name: "equal with matching security list first id",
987+
actual: core.Subnet{
988+
DisplayName: common.String("name"),
989+
CidrBlock: common.String("10.0.0.0/24"),
990+
SecurityListIds: []string{"secid", "other"},
991+
},
992+
desired: infrastructurev1beta2.Subnet{
993+
Name: "name",
994+
CIDR: "10.0.0.0/24",
995+
SecurityList: &infrastructurev1beta2.SecurityList{
996+
ID: secID,
997+
},
998+
},
999+
want: true,
1000+
},
1001+
{
1002+
name: "desired security list id nil",
1003+
actual: core.Subnet{
1004+
DisplayName: common.String("name"),
1005+
CidrBlock: common.String("10.0.0.0/24"),
1006+
SecurityListIds: []string{"secid"},
1007+
},
1008+
desired: infrastructurev1beta2.Subnet{
1009+
Name: "name",
1010+
CIDR: "10.0.0.0/24",
1011+
SecurityList: &infrastructurev1beta2.SecurityList{
1012+
// ID intentionally nil
1013+
},
1014+
},
1015+
want: false,
1016+
},
1017+
{
1018+
name: "desired security list present but actual has none",
1019+
actual: core.Subnet{
1020+
DisplayName: common.String("name"),
1021+
CidrBlock: common.String("10.0.0.0/24"),
1022+
},
1023+
desired: infrastructurev1beta2.Subnet{
1024+
Name: "name",
1025+
CIDR: "10.0.0.0/24",
1026+
SecurityList: &infrastructurev1beta2.SecurityList{
1027+
ID: secID,
1028+
},
1029+
},
1030+
want: false,
1031+
},
1032+
{
1033+
name: "security list id mismatch with first element",
1034+
// we should find the second item in the list
1035+
actual: core.Subnet{
1036+
DisplayName: common.String("name"),
1037+
CidrBlock: common.String("10.0.0.0/24"),
1038+
SecurityListIds: []string{"different", "secid"},
1039+
},
1040+
desired: infrastructurev1beta2.Subnet{
1041+
Name: "name",
1042+
CIDR: "10.0.0.0/24",
1043+
SecurityList: &infrastructurev1beta2.SecurityList{
1044+
ID: secID,
1045+
},
1046+
},
1047+
want: true,
1048+
},
1049+
{
1050+
name: "desired security list nil but actual has ids",
1051+
actual: core.Subnet{
1052+
DisplayName: common.String("name"),
1053+
CidrBlock: common.String("10.0.0.0/24"),
1054+
SecurityListIds: []string{"any"},
1055+
},
1056+
desired: infrastructurev1beta2.Subnet{
1057+
Name: "name",
1058+
CIDR: "10.0.0.0/24",
1059+
},
1060+
want: true,
1061+
},
1062+
}
1063+
1064+
for _, tt := range tests {
1065+
t.Run(tt.name, func(t *testing.T) {
1066+
got := s.IsSubnetsEqual(&tt.actual, tt.desired)
1067+
if got != tt.want {
1068+
t.Errorf("IsSubnetsEqual() = %v, want %v", got, tt.want)
1069+
}
1070+
})
1071+
}
1072+
}

0 commit comments

Comments
 (0)