Skip to content

Commit 8f86fcb

Browse files
committed
bindings: Update to support new constraints
This handles mapping from OvsToNative - min 0, max > 1 && !unlimted to an array - min 0, max 1 to a pointer - min 0, max unlimited to a slice And in NativeToOvs, we convert all cases back in to an OvsSet Signed-off-by: Dave Tucker <[email protected]>
1 parent c68cba9 commit 8f86fcb

File tree

11 files changed

+268
-134
lines changed

11 files changed

+268
-134
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,16 @@ The API to interact with OVSDB is based on tagged golang structs. We call it a M
2222
Config map[string]string `ovsdb:"other_config"`
2323
}
2424

25+
libovsdb is able to translate a Model in to OVSDB format.
26+
To make the API use go idioms, the following mappings occur:
27+
28+
1. OVSDB Set with min 0 and max unlimited = Slice
29+
1. OVSDB Set with min 0 and max 1 = Pointer to scalar type
30+
1. OVSDB Set with min 0 and max N = Array of N
31+
1. OVSDB Enum = Type-aliased Enum Type
32+
1. OVSDB Map = Map
33+
1. OVSDB Scalar Type = Equivalent scalar Go type
34+
2535
A Open vSwitch Database is modeled using a DBModel which is a created by assigning table names to pointers to these structs:
2636

2737
dbModel, _ := model.NewDBModel("OVN_Northbound", map[string]model.Model{

client/api_test.go

Lines changed: 49 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ import (
99
"github.com/ovn-org/libovsdb/model"
1010
"github.com/ovn-org/libovsdb/ovsdb"
1111
"github.com/stretchr/testify/assert"
12+
"github.com/stretchr/testify/require"
13+
)
14+
15+
var (
16+
trueVal = true
17+
falseVal = false
18+
one = 1
19+
six = 6
1220
)
1321

1422
func TestAPIListSimple(t *testing.T) {
@@ -222,25 +230,25 @@ func TestAPIListFields(t *testing.T) {
222230
UUID: aUUID0,
223231
Name: "lsp0",
224232
ExternalIds: map[string]string{"foo": "bar"},
225-
Enabled: []bool{true},
233+
Enabled: &trueVal,
226234
},
227235
&testLogicalSwitchPort{
228236
UUID: aUUID1,
229237
Name: "magiclsp1",
230238
ExternalIds: map[string]string{"foo": "baz"},
231-
Enabled: []bool{false},
239+
Enabled: &falseVal,
232240
},
233241
&testLogicalSwitchPort{
234242
UUID: aUUID2,
235243
Name: "lsp2",
236244
ExternalIds: map[string]string{"unique": "id"},
237-
Enabled: []bool{false},
245+
Enabled: &falseVal,
238246
},
239247
&testLogicalSwitchPort{
240248
UUID: aUUID3,
241249
Name: "magiclsp2",
242250
ExternalIds: map[string]string{"foo": "baz"},
243-
Enabled: []bool{true},
251+
Enabled: &trueVal,
244252
},
245253
}
246254
lspcache := map[string]model.Model{}
@@ -624,22 +632,22 @@ func TestAPIMutate(t *testing.T) {
624632
Name: "lsp0",
625633
Type: "someType",
626634
ExternalIds: map[string]string{"foo": "bar"},
627-
Enabled: []bool{true},
628-
Tag: []int{1},
635+
Enabled: &trueVal,
636+
Tag: &one,
629637
},
630638
aUUID1: &testLogicalSwitchPort{
631639
UUID: aUUID1,
632640
Name: "lsp1",
633641
Type: "someType",
634642
ExternalIds: map[string]string{"foo": "baz"},
635-
Tag: []int{1},
643+
Tag: &one,
636644
},
637645
aUUID2: &testLogicalSwitchPort{
638646
UUID: aUUID2,
639647
Name: "lsp2",
640648
Type: "someOtherType",
641649
ExternalIds: map[string]string{"foo": "baz"},
642-
Tag: []int{1},
650+
Tag: &one,
643651
},
644652
}
645653
testData := cache.Data{
@@ -648,7 +656,6 @@ func TestAPIMutate(t *testing.T) {
648656
tcache := apiTestCache(t, testData)
649657

650658
testObj := testLogicalSwitchPort{}
651-
652659
test := []struct {
653660
name string
654661
condition func(API) ConditionalAPI
@@ -667,16 +674,16 @@ func TestAPIMutate(t *testing.T) {
667674
},
668675
mutations: []model.Mutation{
669676
{
670-
Field: &testObj.Tag,
677+
Field: &testObj.Addresses,
671678
Mutator: ovsdb.MutateOperationInsert,
672-
Value: []int{5},
679+
Value: []string{"1.1.1.1"},
673680
},
674681
},
675682
result: []ovsdb.Operation{
676683
{
677684
Op: ovsdb.OperationMutate,
678685
Table: "Logical_Switch_Port",
679-
Mutations: []ovsdb.Mutation{{Column: "tag", Mutator: ovsdb.MutateOperationInsert, Value: testOvsSet(t, []int{5})}},
686+
Mutations: []ovsdb.Mutation{{Column: "addresses", Mutator: ovsdb.MutateOperationInsert, Value: testOvsSet(t, []string{"1.1.1.1"})}},
680687
Where: []ovsdb.Condition{{Column: "_uuid", Function: ovsdb.ConditionEqual, Value: ovsdb.UUID{GoUUID: aUUID0}}},
681688
},
682689
},
@@ -777,9 +784,9 @@ func TestAPIMutate(t *testing.T) {
777784
cond := tt.condition(api)
778785
ops, err := cond.Mutate(&testObj, tt.mutations...)
779786
if tt.err {
780-
assert.NotNil(t, err)
787+
require.Error(t, err)
781788
} else {
782-
assert.Nil(t, err)
789+
require.Nil(t, err)
783790
assert.ElementsMatchf(t, tt.result, ops, "ovsdb.Operations should match")
784791
}
785792
})
@@ -793,23 +800,23 @@ func TestAPIUpdate(t *testing.T) {
793800
Name: "lsp0",
794801
Type: "someType",
795802
ExternalIds: map[string]string{"foo": "bar"},
796-
Enabled: []bool{true},
797-
Tag: []int{1},
803+
Enabled: &trueVal,
804+
Tag: &one,
798805
},
799806
aUUID1: &testLogicalSwitchPort{
800807
UUID: aUUID1,
801808
Name: "lsp1",
802809
Type: "someType",
803810
ExternalIds: map[string]string{"foo": "baz"},
804-
Tag: []int{1},
805-
Enabled: []bool{true},
811+
Tag: &one,
812+
Enabled: &trueVal,
806813
},
807814
aUUID2: &testLogicalSwitchPort{
808815
UUID: aUUID2,
809816
Name: "lsp2",
810817
Type: "someOtherType",
811818
ExternalIds: map[string]string{"foo": "baz"},
812-
Tag: []int{1},
819+
Tag: &one,
813820
},
814821
}
815822
testData := cache.Data{
@@ -836,7 +843,7 @@ func TestAPIUpdate(t *testing.T) {
836843
},
837844
prepare: func(t *testLogicalSwitchPort) {
838845
t.Type = "somethingElse"
839-
t.Tag = []int{6}
846+
t.Tag = &six
840847
},
841848
result: []ovsdb.Operation{
842849
{
@@ -857,7 +864,7 @@ func TestAPIUpdate(t *testing.T) {
857864
},
858865
prepare: func(t *testLogicalSwitchPort) {
859866
t.Type = "somethingElse"
860-
t.Tag = []int{6}
867+
t.Tag = &six
861868
},
862869
result: []ovsdb.Operation{
863870
{
@@ -874,7 +881,7 @@ func TestAPIUpdate(t *testing.T) {
874881
condition: func(a API) ConditionalAPI {
875882
t := testLogicalSwitchPort{
876883
Type: "sometype",
877-
Enabled: []bool{true},
884+
Enabled: &trueVal,
878885
}
879886
return a.Where(&t, model.Condition{
880887
Field: &t.Type,
@@ -883,7 +890,7 @@ func TestAPIUpdate(t *testing.T) {
883890
})
884891
},
885892
prepare: func(t *testLogicalSwitchPort) {
886-
t.Tag = []int{6}
893+
t.Tag = &six
887894
},
888895
result: []ovsdb.Operation{
889896
{
@@ -908,11 +915,11 @@ func TestAPIUpdate(t *testing.T) {
908915
model.Condition{
909916
Field: &t.Enabled,
910917
Function: ovsdb.ConditionIncludes,
911-
Value: []bool{true},
918+
Value: &trueVal,
912919
})
913920
},
914921
prepare: func(t *testLogicalSwitchPort) {
915-
t.Tag = []int{6}
922+
t.Tag = &six
916923
},
917924
result: []ovsdb.Operation{
918925
{
@@ -925,7 +932,7 @@ func TestAPIUpdate(t *testing.T) {
925932
Op: ovsdb.OperationUpdate,
926933
Table: "Logical_Switch_Port",
927934
Row: tagRow,
928-
Where: []ovsdb.Condition{{Column: "enabled", Function: ovsdb.ConditionIncludes, Value: testOvsSet(t, []bool{true})}},
935+
Where: []ovsdb.Condition{{Column: "enabled", Function: ovsdb.ConditionIncludes, Value: testOvsSet(t, &trueVal)}},
929936
},
930937
},
931938
err: false,
@@ -943,11 +950,11 @@ func TestAPIUpdate(t *testing.T) {
943950
model.Condition{
944951
Field: &t.Enabled,
945952
Function: ovsdb.ConditionIncludes,
946-
Value: []bool{true},
953+
Value: &trueVal,
947954
})
948955
},
949956
prepare: func(t *testLogicalSwitchPort) {
950-
t.Tag = []int{6}
957+
t.Tag = &six
951958
},
952959
result: []ovsdb.Operation{
953960
{
@@ -956,7 +963,7 @@ func TestAPIUpdate(t *testing.T) {
956963
Row: tagRow,
957964
Where: []ovsdb.Condition{
958965
{Column: "type", Function: ovsdb.ConditionEqual, Value: "sometype"},
959-
{Column: "enabled", Function: ovsdb.ConditionIncludes, Value: testOvsSet(t, []bool{true})},
966+
{Column: "enabled", Function: ovsdb.ConditionIncludes, Value: testOvsSet(t, &trueVal)},
960967
},
961968
},
962969
},
@@ -967,7 +974,7 @@ func TestAPIUpdate(t *testing.T) {
967974
condition: func(a API) ConditionalAPI {
968975
t := testLogicalSwitchPort{
969976
Type: "sometype",
970-
Enabled: []bool{true},
977+
Enabled: &trueVal,
971978
}
972979
return a.Where(&t, model.Condition{
973980
Field: &t.Type,
@@ -976,7 +983,7 @@ func TestAPIUpdate(t *testing.T) {
976983
})
977984
},
978985
prepare: func(t *testLogicalSwitchPort) {
979-
t.Tag = []int{6}
986+
t.Tag = &six
980987
},
981988
result: []ovsdb.Operation{
982989
{
@@ -992,12 +999,12 @@ func TestAPIUpdate(t *testing.T) {
992999
name: "select multiple by predicate change multiple field",
9931000
condition: func(a API) ConditionalAPI {
9941001
return a.WhereCache(func(t *testLogicalSwitchPort) bool {
995-
return t.Enabled != nil && t.Enabled[0] == true
1002+
return t.Enabled != nil && *t.Enabled == true
9961003
})
9971004
},
9981005
prepare: func(t *testLogicalSwitchPort) {
9991006
t.Type = "somethingElse"
1000-
t.Tag = []int{6}
1007+
t.Tag = &six
10011008
},
10021009
result: []ovsdb.Operation{
10031010
{
@@ -1041,23 +1048,23 @@ func TestAPIDelete(t *testing.T) {
10411048
Name: "lsp0",
10421049
Type: "someType",
10431050
ExternalIds: map[string]string{"foo": "bar"},
1044-
Enabled: []bool{true},
1045-
Tag: []int{1},
1051+
Enabled: &trueVal,
1052+
Tag: &one,
10461053
},
10471054
aUUID1: &testLogicalSwitchPort{
10481055
UUID: aUUID1,
10491056
Name: "lsp1",
10501057
Type: "someType",
10511058
ExternalIds: map[string]string{"foo": "baz"},
1052-
Tag: []int{1},
1053-
Enabled: []bool{true},
1059+
Tag: &one,
1060+
Enabled: &trueVal,
10541061
},
10551062
aUUID2: &testLogicalSwitchPort{
10561063
UUID: aUUID2,
10571064
Name: "lsp2",
10581065
Type: "someOtherType",
10591066
ExternalIds: map[string]string{"foo": "baz"},
1060-
Tag: []int{1},
1067+
Tag: &one,
10611068
},
10621069
}
10631070
testData := cache.Data{
@@ -1107,7 +1114,7 @@ func TestAPIDelete(t *testing.T) {
11071114
name: "select by field equality",
11081115
condition: func(a API) ConditionalAPI {
11091116
t := testLogicalSwitchPort{
1110-
Enabled: []bool{true},
1117+
Enabled: &trueVal,
11111118
}
11121119
return a.Where(&t, model.Condition{
11131120
Field: &t.Type,
@@ -1128,7 +1135,7 @@ func TestAPIDelete(t *testing.T) {
11281135
name: "select any by field ",
11291136
condition: func(a API) ConditionalAPI {
11301137
t := testLogicalSwitchPort{
1131-
Enabled: []bool{true},
1138+
Enabled: &trueVal,
11321139
}
11331140
return a.Where(&t,
11341141
model.Condition{
@@ -1159,7 +1166,7 @@ func TestAPIDelete(t *testing.T) {
11591166
name: "select all by field ",
11601167
condition: func(a API) ConditionalAPI {
11611168
t := testLogicalSwitchPort{
1162-
Enabled: []bool{true},
1169+
Enabled: &trueVal,
11631170
}
11641171
return a.WhereAll(&t,
11651172
model.Condition{
@@ -1188,7 +1195,7 @@ func TestAPIDelete(t *testing.T) {
11881195
name: "select multiple by predicate",
11891196
condition: func(a API) ConditionalAPI {
11901197
return a.WhereCache(func(t *testLogicalSwitchPort) bool {
1191-
return t.Enabled != nil && t.Enabled[0] == true
1198+
return t.Enabled != nil && *t.Enabled == true
11921199
})
11931200
},
11941201
result: []ovsdb.Operation{

client/api_test_model.go

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,21 +131,21 @@ func (*testLogicalSwitch) Table() string {
131131
//LogicalSwitchPort struct defines an object in Logical_Switch_Port table
132132
type testLogicalSwitchPort struct {
133133
UUID string `ovsdb:"_uuid"`
134-
Up []bool `ovsdb:"up"`
135-
Dhcpv4Options []string `ovsdb:"dhcpv4_options"`
134+
Up *bool `ovsdb:"up"`
135+
Dhcpv4Options *string `ovsdb:"dhcpv4_options"`
136136
Name string `ovsdb:"name"`
137-
DynamicAddresses []string `ovsdb:"dynamic_addresses"`
138-
HaChassisGroup []string `ovsdb:"ha_chassis_group"`
137+
DynamicAddresses *string `ovsdb:"dynamic_addresses"`
138+
HaChassisGroup *string `ovsdb:"ha_chassis_group"`
139139
Options map[string]string `ovsdb:"options"`
140-
Enabled []bool `ovsdb:"enabled"`
140+
Enabled *bool `ovsdb:"enabled"`
141141
Addresses []string `ovsdb:"addresses"`
142-
Dhcpv6Options []string `ovsdb:"dhcpv6_options"`
143-
TagRequest []int `ovsdb:"tag_request"`
144-
Tag []int `ovsdb:"tag"`
142+
Dhcpv6Options *string `ovsdb:"dhcpv6_options"`
143+
TagRequest *int `ovsdb:"tag_request"`
144+
Tag *int `ovsdb:"tag"`
145145
PortSecurity []string `ovsdb:"port_security"`
146146
ExternalIds map[string]string `ovsdb:"external_ids"`
147147
Type string `ovsdb:"type"`
148-
ParentName []string `ovsdb:"parent_name"`
148+
ParentName *string `ovsdb:"parent_name"`
149149
}
150150

151151
// Table returns the table name. It's part of the Model interface

0 commit comments

Comments
 (0)