### Install and Use OVSDB Code Generator (modelgen) Source: https://context7.com/ovn-org/libovsdb/llms.txt Steps to install the modelgen tool, download an OVSDB schema, and generate Go types. Includes a go:generate directive for automation and an example of using the generated models. ```bash # Install modelgen go install github.com/ovn-org/libovsdb/cmd/modelgen@latest # Download schema from running OVSDB server ovsdb-client get-schema "tcp:localhost:6641" > ovn-nb.ovsschema # Generate Go types modelgen -p mypackage -o ./generated ovn-nb.ovsschema # The generated package will contain: # - A struct for each table in the schema # - A FullDatabaseModel() function that returns a ready-to-use ClientDBModel ``` ```go // gen.go - Add go:generate directive package mypackage //go:generate modelgen -p mypackage -o . ovn-nb.ovsschema ``` ```go // Using generated models package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" generated "example.com/myapp/generated" ) func main() { // Use the generated FullDatabaseModel dbModel, err := generated.FullDatabaseModel() if err != nil { log.Fatal(err) } ovs, err := client.NewOVSDBClient(dbModel, client.WithEndpoint("tcp:localhost:6641"), ) if err != nil { log.Fatal(err) } err = ovs.Connect(context.Background()) if err != nil { log.Fatal(err) } defer ovs.Close() ovs.MonitorAll(context.Background()) // Use generated types var routers []generated.LogicalRouter ovs.List(context.Background(), &routers) } ``` -------------------------------- ### Get libovsdb and Set Up Development Environment Source: https://github.com/ovn-org/libovsdb/blob/main/HACKING.md Clone the libovsdb repository and navigate to the source directory. Ensure your Go environment is set up. ```bash go get github.com/ovn-org/libovsdb cd $GOPATH/src/github.com/ovn-org/libovsdb ``` -------------------------------- ### Generate and Use Go Models Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Example of downloading an OVSDB schema, generating Go models using modelgen, and then using these models to interact with the database. ```bash ovsdb-client get-schema "tcp:localhost:6641" > mypackage/ovs-nb.ovsschema ``` ```bash cat < mypackage/gen.go package mypackage // go:generate modelgen -p mypackage -o . ovs-nb.ovsschema EOF go generate ./... ``` ```go import ( "fmt" "github.com/ovn-org/libovsdb/client" generated "example.com/example/mypackage" ) func main() { dbModelReq, _ := generated.FullDatabaseModel() ovs, _ := client.Connect(context.Background(), dbModelReq, client.WithEndpoint("tcp:localhost:6641")) ovs.MonitorAll() // Create a *LogicalRouter, as a pointer to a Model is required by the API lr := &generated.LogicalRouter{ Name: "myRouter", } ovs.Get(lr) fmt.Printf("My Router has UUID: %s and %d Ports\n", lr.UUID, len(lr.Ports)) } ``` -------------------------------- ### Define Client Index for Map Key Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Example of setting a client index on a specific map key within a column. This allows for efficient lookups based on the value associated with that key. ```go dbModel, err := nbdb.FullDatabaseModel() dbModel.SetIndexes(map[string][]model.ClientIndex{ "Load_Balancer": {{Columns: []model.ColumnKey{{Column: "external_ids", Key: "myIdKey"}}}}, }) // connect .... l := &LoadBalancer{ ExternalIds: map[string]string{"myIdKey": "myIdValue"}, } // quick indexed result ovn.Where(lb).List(ctx, &results) ``` -------------------------------- ### Handle OVSDB Cache Events in Go Source: https://context7.com/ovn-org/libovsdb/llms.txt Implement event handlers to react to changes in the OVSDB cache. This example shows how to register functions for add, update, and delete events for 'Logical_Switch' table. ```go package main import ( "context" "fmt" "log" "github.com/ovn-org/libovsdb/cache" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" ) func main() { // ... client setup ... ctx := context.Background() // Add event handler before starting monitor ovs.Cache().AddEventHandler(&cache.EventHandlerFuncs{ AddFunc: func(table string, m model.Model) { if table == "Logical_Switch" { ls := m.(*LogicalSwitch) fmt.Printf("New switch added: %s (UUID: %s)\n", ls.Name, ls.UUID) } }, UpdateFunc: func(table string, old, new model.Model) { if table == "Logical_Switch" { oldLS := old.(*LogicalSwitch) newLS := new.(*LogicalSwitch) fmt.Printf("Switch %s updated: ports %d -> %d\n", newLS.Name, len(oldLS.Ports), len(newLS.Ports)) } }, DeleteFunc: func(table string, m model.Model) { if table == "Logical_Switch" { ls := m.(*LogicalSwitch) fmt.Printf("Switch deleted: %s\n", ls.Name) } }, }) // Start monitoring _, err := ovs.MonitorAll(ctx) if err != nil { log.Fatal(err) } // Wait for disconnect notification <-ovs.DisconnectNotify() log.Println("Disconnected from server") } ``` -------------------------------- ### Slow Predicate Example Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Illustrates a less performant way to filter data by running a predicate function on all rows of a table. This is typically slower than using indexed operations. ```go // slow predicate run on all the LB table rows... ovn.WhereCache(func (lb *LoadBalancer) bool { return lb.ExternalIds["myIdKey"] == "myIdValue" }).List(ctx, &results) ``` -------------------------------- ### Set Client Indexes for Faster OVSDB Queries in Go Source: https://context7.com/ovn-org/libovsdb/llms.txt Improve query performance by defining custom indexes on OVSDB tables. This example demonstrates indexing the 'Load_Balancer' table by a specific key within 'external_ids' and by multiple columns. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" ) func main() { dbModel, _ := model.NewClientDBModel("OVN_Northbound", map[string]model.Model{ "Load_Balancer": &LoadBalancer{}, }) // Set custom indexes for faster lookups dbModel.SetIndexes(map[string][]model.ClientIndex{ "Load_Balancer": { // Index by a specific key in external_ids map {Columns: []model.ColumnKey{{Column: "external_ids", Key: "myIdKey"}}}, // Index by multiple columns {Columns: []model.ColumnKey{{Column: "name"}, {Column: "vips"}}}, }, }) ovs, _ := client.NewOVSDBClient(dbModel, client.WithEndpoint("tcp:localhost:6641")) ovs.Connect(context.Background()) ovs.MonitorAll(context.Background()) // Now lookups using indexed fields are fast lb := &LoadBalancer{ ExternalIDs: map[string]string{"myIdKey": "myIdValue"}, } var results []LoadBalancer // This uses the index instead of scanning all rows err := ovs.Where(lb).List(context.Background(), &results) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Get a Database Element Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Retrieve a specific element from the database using its indexed fields. The Get method requires a pointer to a model instance. ```go ls := &MyLogicalSwitch{Name: "foo"} // "name" is in the table index list ovs.Get(ls) ``` -------------------------------- ### Get Single Row Source: https://context7.com/ovn-org/libovsdb/llms.txt Retrieve a single row by providing a model instance populated with a UUID or a schema-defined index. ```go package main import ( "context" "fmt" "log" "github.com/ovn-org/libovsdb/client" ) func main() { // ... client setup and monitor ... ctx := context.Background() // Get by UUID ls := &LogicalSwitch{UUID: "550e8400-e29b-41d4-a716-446655440000"} err := ovs.Get(ctx, ls) if err == client.ErrNotFound { log.Println("Switch not found") return } else if err != nil { log.Fatalf("failed to get: %v", err) } fmt.Printf("Found switch: %s with %d ports\n", ls.Name, len(ls.Ports)) // Get by index (e.g., name is often an index) ls = &LogicalSwitch{Name: "my-switch"} err = ovs.Get(ctx, ls) if err == client.ErrNotFound { log.Println("Switch not found by name") return } fmt.Printf("Found switch UUID: %s\n", ls.UUID) } ``` -------------------------------- ### Connect to OVSDB and Monitor Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Establishes a connection to an OVSDB endpoint using the defined database model. `MonitorAll` is called to enable the built-in cache. ```go ovs, _ := client.Connect(context.Background(), dbModelReq, client.WithEndpoint("tcp:172.18.0.4:6641")) client.MonitorAll(nil) // Only needed if you want to use the built-in cache ``` -------------------------------- ### Run Tests and Format Code Source: https://github.com/ovn-org/libovsdb/blob/main/HACKING.md Before creating a pull request, run all tests using 'fig up -d' and 'make test-all', and ensure your code is formatted with 'go fmt'. ```bash # Run all the tests fig up -d make test-all # Make sure your code is pretty go fmt ``` -------------------------------- ### Run Integration Tests with Docker Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Instructions for setting up and running integration tests using Docker. This involves setting the Docker IP and running a test command within a Docker container. ```bash export DOCKER_IP=$(boot2docker ip) docker-compose run test /bin/sh # make test-local ... # exit docker-compose down ``` -------------------------------- ### Connect to OVSDB Server with Options Source: https://context7.com/ovn-org/libovsdb/llms.txt Create an OVSDB client using NewOVSDBClient, specifying connection options like endpoint, TLS configuration, and automatic reconnection. The client must be connected using `Connect()` and closed with `Close()`. ```Go package main import ( "context" "crypto/tls" "log" "time" "github.com/cenkalti/backoff/v4" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" ) func main() { dbModel, _ := model.NewClientDBModel("Open_vSwitch", map[string]model.Model{ "Bridge": &Bridge{}, }) // Create client with Unix socket (default) ovs, err := client.NewOVSDBClient(dbModel) if err != nil { log.Fatal(err) } // Or with TCP endpoint ovs, err = client.NewOVSDBClient(dbModel, client.WithEndpoint("tcp:192.168.1.100:6640"), ) // Or with SSL and TLS config tlsConfig := &tls.Config{ InsecureSkipVerify: true, } ovs, err = client.NewOVSDBClient(dbModel, client.WithEndpoint("ssl:192.168.1.100:6640"), client.WithTLSConfig(tlsConfig), ) // With automatic reconnection ovs, err = client.NewOVSDBClient(dbModel, client.WithEndpoint("tcp:192.168.1.100:6640"), client.WithReconnect(5*time.Second, backoff.NewExponentialBackOff()), ) // Connect with leader-only mode (for clustered databases) ovs, err = client.NewOVSDBClient(dbModel, client.WithEndpoint("tcp:192.168.1.100:6640"), client.WithLeaderOnly(true), ) // Connect to the server ctx := context.Background() err = ovs.Connect(ctx) if err != nil { log.Fatalf("failed to connect: %v", err) } defer ovs.Close() // Check connection status if ovs.Connected() { log.Printf("Connected to: %s", ovs.CurrentEndpoint()) } ``` -------------------------------- ### Create OVSDB Client DBModel Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Creates a client database model by assigning table names to pointers of Go struct models. This is used to initialize the OVSDB client. ```go dbModelReq, _ := model.NewClientDBModel("OVN_Northbound", map[string]model.Model{ "Logical_Switch": &MyLogicalSwitch{}, }) ``` -------------------------------- ### Fork the Repository using Hub Source: https://github.com/ovn-org/libovsdb/blob/main/HACKING.md Use the 'hub' tool to fork the libovsdb repository on GitHub. ```bash hub fork ``` -------------------------------- ### List Database Content Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Use the List method to retrieve all entries from a table. The result is a pointer to a slice of models. ```go var lsList *[]MyLogicalSwitch ovs.List(lsList) for _, ls := range lsList { fmt.Printf("%+v\n", ls) } ``` -------------------------------- ### List Rows from Cache Source: https://context7.com/ovn-org/libovsdb/llms.txt Populate a slice with rows from the local cache. Supports both value and pointer slices, and capacity limiting. ```go package main import ( "context" "fmt" "log" "github.com/ovn-org/libovsdb/client" ) func main() { // ... client setup and monitor ... ctx := context.Background() // List all LogicalSwitches var switches []LogicalSwitch err := ovs.List(ctx, &switches) if err != nil { log.Fatalf("failed to list: %v", err) } for _, ls := range switches { fmt.Printf("UUID: %s, Name: %s, Ports: %d\n", ls.UUID, ls.Name, len(ls.Ports)) } // List can also work with pointers var switchPtrs []*LogicalSwitch err = ovs.List(ctx, &switchPtrs) if err != nil { log.Fatal(err) } // List with a capacity limit (only fills up to capacity) limitedSwitches := make([]LogicalSwitch, 0, 10) // Only get first 10 err = ovs.List(ctx, &limitedSwitches) } ``` -------------------------------- ### Combine OVSDB Operations in a Transaction with Go Source: https://context7.com/ovn-org/libovsdb/llms.txt Shows how to group multiple OVSDB operations (create, mutate) into a single atomic transaction using Transact. Ensures all operations succeed or fail together. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" ) func main() { // ... client setup and monitor ... ctx := context.Background() // Create a new switch and add it to the root table bridge := &Bridge{ UUID: "newbridge", // Named UUID Name: "br-new", } createOps, err := ovs.Create(bridge) if err != nil { log.Fatal(err) } // Mutate the root Open_vSwitch row to include the new bridge root := &OpenVSwitch{UUID: "root-uuid"} mutateOps, err := ovs.Where(root).Mutate(root, model.Mutation{ Field: &root.Bridges, Mutator: ovsdb.MutateOperationInsert, Value: []string{bridge.UUID}, // Reference by named UUID }, ) if err != nil { log.Fatal(err) } // Combine all operations allOps := append(createOps, mutateOps...) // Execute atomically results, err := ovs.Transact(ctx, allOps...) if err != nil { log.Fatal(err) } // Verify all operations succeeded opErrs, err := ovsdb.CheckOperationResults(results, allOps) if err != nil { log.Fatalf("Transaction failed: ops=%v, err=%v", opErrs, err) } log.Printf("Created bridge with UUID: %s", results[0].UUID.GoUUID) } ``` -------------------------------- ### Create OVSDB Client DB Model Source: https://context7.com/ovn-org/libovsdb/llms.txt Create a ClientDBModel to map table names to Go struct types, representing the database schema. This is necessary before creating an OVSDB client. ```Go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" ) func main() { // Create a database model mapping table names to Go struct types dbModel, err := model.NewClientDBModel("OVN_Northbound", map[string]model.Model{ "Logical_Switch": &MyLogicalSwitch{}, "Logical_Router": &MyLogicalRouter{}, }) if err != nil { log.Fatalf("failed to create db model: %v", err) } // Output: Database model for "OVN_Northbound" with 2 tables ``` -------------------------------- ### Create a New Database Element Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Generate transaction operations to create a new element. The Create method takes a model instance and returns operations to be transacted. ```go ops, _ := ovs.Create(&MyLogicalSwitch{ Name: "foo", }) ovs.Transact(ops...) ``` -------------------------------- ### libovsdb Condition Operators Source: https://context7.com/ovn-org/libovsdb/llms.txt Demonstrates the use of various condition operators like Equal, NotEqual, Includes, and Excludes for filtering OVSDB data. These are used with WhereAny and WhereAll functions. ```go package main import ( "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" ) func conditionExamples() { ls := &LogicalSwitch{} // Equal - exact match cond1 := model.Condition{ Field: &ls.Name, Function: ovsdb.ConditionEqual, // "==" Value: "my-switch", } // Not Equal cond2 := model.Condition{ Field: &ls.Name, Function: ovsdb.ConditionNotEqual, // "!=" Value: "excluded-switch", } // Includes - for maps and sets (contains all elements) cond3 := model.Condition{ Field: &ls.ExternalIDs, Function: ovsdb.ConditionIncludes, // "includes" Value: map[string]string{"env": "prod"}, } // Excludes - for maps and sets (does not contain) cond4 := model.Condition{ Field: &ls.ExternalIDs, Function: ovsdb.ConditionExcludes, // "excludes" Value: map[string]string{"deprecated": "true"}, } // Comparison operators (for numeric fields) // ConditionLessThan "<" // ConditionLessThanOrEqual "<=" // ConditionGreaterThan ">" // ConditionGreaterThanOrEqual ">=" _ = []model.Condition{cond1, cond2, cond3, cond4} } ``` -------------------------------- ### Create Database Rows Source: https://context7.com/ovn-org/libovsdb/llms.txt Generate insert operations and execute them via a transaction. Use named UUIDs to reference new rows within the same transaction. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/ovsdb" ) func main() { // ... client setup and monitor ... ctx := context.Background() // Create a single row ls := &LogicalSwitch{ UUID: "myswitch", // Named UUID (will be replaced by real UUID) Name: "new-switch", ExternalIDs: map[string]string{ "owner": "my-app", }, } ops, err := ovs.Create(ls) if err != nil { log.Fatalf("failed to create operations: %v", err) } // Execute the transaction results, err := ovs.Transact(ctx, ops...) if err != nil { log.Fatalf("transaction failed: %v", err) } // Check results opErrs, err := ovsdb.CheckOperationResults(results, ops) if err != nil { log.Fatalf("operation errors: %v, %v", opErrs, err) } // Get the real UUID from the result realUUID := results[0].UUID.GoUUID log.Printf("Created switch with UUID: %s", realUUID) // Create multiple rows in one transaction ls1 := &LogicalSwitch{UUID: "switch1", Name: "switch-1"} ls2 := &LogicalSwitch{UUID: "switch2", Name: "switch-2"} ops, err = ovs.Create(ls1, ls2) if err != nil { log.Fatal(err) } results, err = ovs.Transact(ctx, ops...) } ``` -------------------------------- ### Generate Go Models from OVSDB Schema Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Use the modelgen tool to automatically generate Go struct definitions for OVSDB tables. This simplifies interaction with the database by providing type safety. ```bash go install github.com/ovn-org/libovsdb/cmd/modelgen $GOPATH/bin/modelgen -p ${PACKAGE_NAME} -o {OUT_DIR} ${OVSDB_SCHEMA} Usage of modelgen: modelgen [flags] OVS_SCHEMA Flags: -d Dry run -o string Directory where the generated files shall be stored (default ".") -p string Package name (default "ovsmodel") ``` -------------------------------- ### Push Changes and Create Pull Request Source: https://github.com/ovn-org/libovsdb/blob/main/HACKING.md Push your local branch to your remote fork and then use 'hub pull-request' to create a pull request on GitHub. ```bash git push hub pull-request ``` -------------------------------- ### Monitor Database Updates with Event Handlers Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Register an event handler to receive notifications for add, delete, and update operations on database tables. The handler can filter events by table name. ```go handler := &cache.EventHandlerFuncs{ AddFunc: func(table string, model model.Model) { if table == "Logical_Switch" { fmt.Printf("A new switch named %s was added!!\n!", model.(*MyLogicalSwitch).Name) } }, } ovs.Cache.AddEventHandler(handler) ``` -------------------------------- ### List Rows using WhereCache() Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Filters rows from the local cache using a provided function. This can be used for cache operations like `List()`. The table is inferred from the function's argument type. ```go lsList := []LogicalSwitch{} ovs.WhereCache( func(ls *MyLogicalSwitch) bool { return strings.HasPrefix(ls.Name, "ext_") }).List(&lsList) ``` -------------------------------- ### libovsdb Mutation Operators Source: https://context7.com/ovn-org/libovsdb/llms.txt Illustrates the use of mutation operators such as Insert and Delete for modifying OVSDB data. These are used with the Mutate function. ```go package main import ( "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" ) func mutationExamples() { ls := &LogicalSwitch{} // Insert - add to map or set mut1 := model.Mutation{ Field: &ls.ExternalIDs, Mutator: ovsdb.MutateOperationInsert, // "insert" Value: map[string]string{"key": "value"}, } // Delete - remove from map or set mut2 := model.Mutation{ Field: &ls.Ports, Mutator: ovsdb.MutateOperationDelete, // "delete" Value: []string{"port-uuid-to-remove"}, } // Arithmetic mutations (for integer fields) // MutateOperationAdd "+=" // MutateOperationSubtract "-=" // MutateOperationMultiply "*=" // MutateOperationDivide "/=" // MutateOperationModulo "%=" _ = []model.Mutation{mut1, mut2} } ``` -------------------------------- ### Define OVSDB Model Struct Source: https://context7.com/ovn-org/libovsdb/llms.txt Define a Go struct with `ovsdb` tags to map database columns. The `_uuid` field is mandatory. Optional fields should be pointers. ```Go type MyLogicalSwitch struct { UUID string `ovsdb:"_uuid"` // Required _uuid field Name string `ovsdb:"name"` Ports []string `ovsdb:"ports"` ExternalIDs map[string]string `ovsdb:"external_ids"` Enabled *bool `ovsdb:"enabled"` // Optional field (pointer) } // Type mappings: // - OVSDB Set (min 0, max unlimited) -> Go Slice // - OVSDB Set (min 0, max 1) -> Go Pointer to scalar // - OVSDB Map -> Go Map // - OVSDB Scalar -> Go Scalar (string, int, bool, float64) ``` -------------------------------- ### Monitor OVSDB Tables Source: https://context7.com/ovn-org/libovsdb/llms.txt Monitor all tables or specific tables with optional field filtering and conditional logic. Use MonitorCancel to stop monitoring. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" ) func main() { // ... client setup ... ctx := context.Background() // Monitor all tables defined in the model cookie, err := ovs.MonitorAll(ctx) if err != nil { log.Fatalf("failed to monitor: %v", err) } log.Printf("Monitor started with cookie: %v", cookie) // Or monitor specific tables with specific fields monitor := ovs.NewMonitor( client.WithTable(&Bridge{}), client.WithTable(&Port{}, &Port{}.Name, &Port{}.Interfaces), // Monitor only specific fields ) cookie, err = ovs.Monitor(ctx, monitor) if err != nil { log.Fatalf("failed to start monitor: %v", err) } // Monitor with conditions (conditional monitoring) monitor = ovs.NewMonitor( client.WithConditionalTable( &Bridge{}, []model.Condition{ { Field: &Bridge{}.Name, Function: ovsdb.ConditionEqual, Value: "br-int", }, }, ), ) cookie, err = ovs.Monitor(ctx, monitor) // Cancel a monitor err = ovs.MonitorCancel(ctx, cookie) } ``` -------------------------------- ### Add Fork as a Remote Repository Source: https://github.com/ovn-org/libovsdb/blob/main/HACKING.md Alternatively, manually fork the repository on GitHub and add your fork as a remote Git repository. ```bash git remote add git@github.com:/libovsdb ``` -------------------------------- ### Search Cache with Predicate Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Filter elements in the cache using a predicate function with the WhereCache method. This is useful for searching based on specific criteria. ```go var lsList *[]MyLogicalSwitch ovs.WhereCache( func(ls *MyLogicalSwitch) bool { return strings.HasPrefix(ls.Name, "ext_") }).List(&lsList) for _, ls := range lsList { fmt.Printf("%+v\n", ls) } ``` -------------------------------- ### Mutate Rows in OVSDB with Go Source: https://context7.com/ovn-org/libovsdb/llms.txt Demonstrates atomic modifications to OVSDB table fields using Mutate operations. Supports inserting/deleting from maps and sets. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" ) func main() { // ... client setup and monitor ... ctx := context.Background() ls := &LogicalSwitch{UUID: "myswitch-uuid"} // Insert into a map ops, err := ovs.Where(ls).Mutate(ls, model.Mutation{ Field: &ls.ExternalIDs, Mutator: ovsdb.MutateOperationInsert, Value: map[string]string{"new-key": "new-value"}, }, ) if err != nil { log.Fatal(err) } _, err = ovs.Transact(ctx, ops...) // Delete from a map ops, err = ovs.Where(ls).Mutate(ls, model.Mutation{ Field: &ls.ExternalIDs, Mutator: ovsdb.MutateOperationDelete, Value: map[string]string{"key-to-remove": ""}, }, ) // Insert into a set (slice) ops, err = ovs.Where(ls).Mutate(ls, model.Mutation{ Field: &ls.Ports, Mutator: ovsdb.MutateOperationInsert, Value: []string{"new-port-uuid"}, }, ) // Delete from a set ops, err = ovs.Where(ls).Mutate(ls, model.Mutation{ Field: &ls.Ports, Mutator: ovsdb.MutateOperationDelete, Value: []string{"port-to-remove"}, }, ) // Multiple mutations in one operation ops, err = ovs.Where(ls).Mutate(ls, model.Mutation{ Field: &ls.ExternalIDs, Mutator: ovsdb.MutateOperationInsert, Value: map[string]string{"key1": "val1"}, }, model.Mutation{ Field: &ls.Ports, Mutator: ovsdb.MutateOperationInsert, Value: []string{"port1", "port2"}, }, ) _, err = ovs.Transact(ctx, ops...) } ``` -------------------------------- ### List Rows Using a Cache Predicate Function Source: https://context7.com/ovn-org/libovsdb/llms.txt Use WhereCache with a custom predicate function to filter rows from the local cache. This is useful for complex client-side filtering. ```go package main import ( "context" "log" "strings" "github.com/ovn-org/libovsdb/client" ) func main() { // ... client setup and monitor ... ctx := context.Background() // List with a predicate function var extSwitches []LogicalSwitch err := ovs.WhereCache(func(ls *LogicalSwitch) bool { return strings.HasPrefix(ls.Name, "ext_") }).List(ctx, &extSwitches) if err != nil { log.Fatal(err) } log.Printf("Found %d external switches", len(extSwitches)) // Delete using cache predicate (creates UUID-based conditions) ops, err := ovs.WhereCache(func(ls *LogicalSwitch) bool { return ls.ExternalIDs["deprecated"] == "true" }).Delete() if err != nil { log.Fatal(err) } _, err = ovs.Transact(ctx, ops...) // Complex filtering with multiple criteria var matchingSwitches []LogicalSwitch err = ovs.WhereCache(func(ls *LogicalSwitch) bool { hasOwner := ls.ExternalIDs["owner"] != "" hasMoreThanFivePorts := len(ls.Ports) > 5 return hasOwner && hasMoreThanFivePorts }).List(ctx, &matchingSwitches) } ``` -------------------------------- ### Delete Rows using WhereAny() with Conditions Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Creates delete operations where rows matching *any* of the specified conditions are affected. Each condition object includes a field, a comparison function, and a value. ```go ls := &LogicalSwitch{} ops, _ := ovs.WhereAny(ls, client.Condition{ Field: &ls.Config, Function: ovsdb.ConditionIncludes, Value: map[string]string{"foo": "bar"}, }).Delete() ``` -------------------------------- ### Delete Database Element with List of Conditions Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Delete elements based on a list of conditions. This allows for more complex filtering before deletion. ```go ops, _ := ovs.Where(ls, client.Condition{ Field: &ls.Config, Function: ovsdb.ConditionIncludes, Value: map[string]string{"foo": "bar"}, }).Delete() ovs.Transact(ops...) ``` -------------------------------- ### Delete Database Element with Multiple Conditions Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Delete elements that satisfy all specified conditions using the WhereAll method. This is useful for precise data removal. ```go ops, _ := ovs.WhereAll(ls, client.Condition{ Field: &ls.Config, Function: ovsdb.ConditionIncludes, Value: map[string]string{"foo": "bar"}, }, client.Condition{ Field: &ls.Config, Function: ovsdb.ConditionIncludes, Value: map[string]string{"bar": "baz"}, }).Delete() ovs.Transact(ops...) ``` -------------------------------- ### Delete Rows by UUID or Index Source: https://context7.com/ovn-org/libovsdb/llms.txt Use Where to specify conditions for deleting rows. You can target rows by their UUID or by indexed fields like 'Name'. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" ) func main() { // ... client setup and monitor ... ctx := context.Background() // Where by UUID (most common) ls := &LogicalSwitch{UUID: "550e8400-e29b-41d4-a716-446655440000"} ops, err := ovs.Where(ls).Delete() if err != nil { log.Fatal(err) } _, err = ovs.Transact(ctx, ops...) // Where by index (e.g., name) ls = &LogicalSwitch{Name: "my-switch"} ops, err = ovs.Where(ls).Delete() // Where with multiple models (OR semantics - matches any) ls1 := &LogicalSwitch{Name: "switch-1"} ls2 := &LogicalSwitch{Name: "switch-2"} ops, err = ovs.Where(ls1, ls2).Delete() // Deletes switch-1 OR switch-2 } ``` -------------------------------- ### Delete Rows from OVSDB with Go Source: https://context7.com/ovn-org/libovsdb/llms.txt Demonstrates deleting rows from OVSDB tables based on various criteria. Supports deletion by UUID, name, or using a WhereCache function. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/ovsdb" ) func main() { // ... client setup and monitor ... ctx := context.Background() // Delete by UUID ls := &LogicalSwitch{UUID: "550e8400-e29b-41d4-a716-446655440000"} ops, err := ovs.Where(ls).Delete() if err != nil { log.Fatal(err) } results, err := ovs.Transact(ctx, ops...) if err != nil { log.Fatal(err) } log.Printf("Deleted %d rows", results[0].Count) // Delete by name ls = &LogicalSwitch{Name: "switch-to-delete"} ops, err = ovs.Where(ls).Delete() // Delete multiple by WhereCache ops, err = ovs.WhereCache(func(ls *LogicalSwitch) bool { return ls.ExternalIDs["temp"] == "true" }).Delete() _, err = ovs.Transact(ctx, ops...) } ``` -------------------------------- ### Delete Rows using Where() Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Generates delete operations based on index information from provided models. It uses the first available index (e.g., `_uuid`) to create a condition. ```go ls := &LogicalSwitch{UUID: "foo"} ls2 := &LogicalSwitch{UUID: "foo2"} ops, _ := ovs.Where(ls, ls2).Delete() ``` -------------------------------- ### Update All Mutable Fields of a Row Source: https://context7.com/ovn-org/libovsdb/llms.txt Fetch a row first, then modify its fields and use Where to specify the row to update. Immutable fields are automatically ignored during the update. ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/ovsdb" ) func main() { // ... client setup and monitor ... ctx := context.Background() // First, get the current row ls := &LogicalSwitch{Name: "my-switch"} err := ovs.Get(ctx, ls) if err != nil { log.Fatal(err) } // Update all mutable fields (immutable fields are automatically ignored) ls.ExternalIDs["updated"] = "true" ops, err := ovs.Where(ls).Update(ls) if err != nil { log.Fatal(err) } _, err = ovs.Transact(ctx, ops...) // Update only specific fields (pass field pointers) ls.ExternalIDs = map[string]string{"env": "staging"} ops, err = ovs.Where(ls).Update(ls, &ls.ExternalIDs) // Only update ExternalIDs if err != nil { log.Fatal(err) } results, err := ovs.Transact(ctx, ops...) if err != nil { log.Fatal(err) } // Check how many rows were updated if results[0].Count > 0 { log.Printf("Updated %d rows", results[0].Count) } } ``` -------------------------------- ### Sign Off Commits Source: https://github.com/ovn-org/libovsdb/blob/main/HACKING.md Add the 'Signed-off-by' trailer to your commit messages to agree to the Developer Certificate of Origin. This is automatically appended by 'git commit -s'. ```bash git commit -s ``` ```text Signed-off-by: John Doe ``` -------------------------------- ### Define OVSDB Model in Go Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Defines a Go struct to represent an OVSDB table, mapping Go types to OVSDB schema. The `_uuid` tag is mandatory for all models. ```go type MyLogicalSwitch struct { UUID string `ovsdb:"_uuid"` // _uuid tag is mandatory Name string `ovsdb:"name"` Ports []string `ovsdb:"ports"` Config map[string]string `ovsdb:"other_config"` } ``` -------------------------------- ### Update a Database Element Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Modify an existing element and generate transaction operations for the update. The Update method requires a condition specified via Where. ```go ls.Config["foo"] = "bar" ops, _ := ovs.Where(ls).Update(&ls) ovs.Transact(ops...) ``` -------------------------------- ### Mutate a Database Element Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Apply mutations to specific fields of a database element. The Mutate method allows for operations like inserting, deleting, or updating field values. ```go ops, _ := ovs.Where(ls).Mutate(ls, ovsdb.Mutation { Field: &ls.Config, Mutator: ovsdb.MutateOperationInsert, Value: map[string]string{"foo": "bar"}, }) ovs.Transact(ops...) ``` -------------------------------- ### Delete Rows with Explicit OR Conditions Source: https://context7.com/ovn-org/libovsdb/llms.txt Use WhereAny with explicit conditions to delete rows that satisfy any of the specified criteria (OR logic). ```go package main import ( "context" "log" "github.com/ovn-org/libovsdb/client" "github.com/ovn-org/libovsdb/model" "github.com/ovn-org/libovsdb/ovsdb" ) func main() { // ... client setup and monitor ... ctx := context.Background() ls := &LogicalSwitch{} // WhereAny - matches rows that satisfy ANY of the conditions (OR) ops, err := ovs.WhereAny(ls, model.Condition{ Field: &ls.Name, Function: ovsdb.ConditionEqual, Value: "switch-1", }, model.Condition{ Field: &ls.Name, Function: ovsdb.ConditionEqual, Value: "switch-2", }, ).Delete() // Deletes all switches named "switch-1" OR "switch-2" // WhereAll - matches rows that satisfy ALL conditions (AND) ops, err = ovs.WhereAll(ls, model.Condition{ Field: &ls.ExternalIDs, Function: ovsdb.ConditionIncludes, Value: map[string]string{"env": "production"}, }, model.Condition{ Field: &ls.ExternalIDs, Function: ovsdb.ConditionIncludes, Value: map[string]string{"owner": "team-a"}, }, ).Delete() // Deletes switches that have BOTH env=production AND owner=team-a _, err = ovs.Transact(ctx, ops...) if err != nil { log.Fatal(err) } } ``` -------------------------------- ### Delete a Database Element by UUID Source: https://github.com/ovn-org/libovsdb/blob/main/README.md Remove an element from the database using its UUID. The Delete method requires a condition, typically specified using the Where clause with the UUID. ```go ls := &LogicalSwitch{UUID:"myUUID"} ops, _ := ovs.Where(ls).Delete() ovs.Transact(ops...) ``` -------------------------------- ### Force Push Updates to Pull Request Source: https://github.com/ovn-org/libovsdb/blob/main/HACKING.md To update an existing pull request after making changes in response to review comments, force push your branch to the remote repository. ```bash git push --force ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.