Documentation ¶
Overview ¶
Package client connects to, monitors and interacts with OVSDB servers (RFC7047).
This package uses structs, that contain the 'ovs' field tag to determine which field goes to which column in the database. We refer to pointers to this structs as Models. Example:
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"` }
Based on these Models a Database Model (see DBModel type) is built to represent the entire OVSDB:
dbModel, _ := client.NewDBModel("OVN_Northbound", map[string]client.Model{ "Logical_Switch": &MyLogicalSwitch{}, })
The DBModel represents the entire Database (or the part of it we're interested in). Using it, the libovsdb.client package is able to properly encode and decode OVSDB messages and store them in Model instances. A client instance is created by simply specifying the connection information and the database model:
ovs, _ := client.Connect(contect.Background(), dbModel)
Main API ¶
After creating a OvsdbClient using the Connect() function, we can use a number of CRUD-like to interact with the database: List(), Get(), Create(), Update(), Mutate(), Delete().
The specific database table that the operation targets is automatically determined based on the type of the parameter.
In terms of return values, some of these functions like Create(), Update(), Mutate() and Delete(), interact with the database so they return list of ovsdb.Operation objects that can be grouped together and passed to client.Transact().
Others, such as List() and Get(), interact with the client's internal cache and are able to return Model instances (or a list thereof) directly.
Conditions ¶
Some API functions (Create() and Get()), can be run directly. Others, require us to use a ConditionalAPI. The ConditionalAPI injects RFC7047 Conditions into ovsdb Operations as well as uses the Conditions to search the internal cache.
The ConditionalAPI is created using the Where(), WhereCache() and WhereAll() functions.
Where() accepts a Model (pointer to a struct with ovs tags) and a number of Condition instances. Conditions must refer to fields of the provided Model (via pointer to fields). Example:
ls = &MyLogicalSwitch {} ovs.Where(ls, client.Condition { Field: &ls.Ports, Function: ovsdb.ConditionIncludes, Value: []string{"portUUID"}, })
If no client.Condition is provided, the client will create a default Condition based on the Model's data. The first non-null field that corresponds to a database index will be used. Therefore the following two statements are equivalent:
ls = &MyLogicalSwitch {UUID:"myUUID"} ovs.Where(ls) ovs.Where(ls, client.Condition { Field: &ls.UUID, Function: ovsdb.ConditionEqual, Value: "myUUID"}, })
Where() accepts multiple Condition instances (through variadic arguments). If provided, the client will generate multiple operations each matching one condition. For example, the following operation will delete all the Logical Switches named "foo" OR "bar":
ops, err := ovs.Where(ls, client.Condition { Field: &ls.Name Function: ovsdb.ConditionEqual, Value: "foo", },client.Condition { Field: &ls.Port, Function: ovsdb.ConditionIncludes, Value: "bar", }).Delete()
To create a Condition that matches all of the conditions simultaneously (i.e: AND semantics), use WhereAll().
Where() and WhereAll() inject conditions into operations that will be evaluated by the server. However, to perform searches on the local cache, a more flexible mechanism is available: WhereCache()
WhereCache() accepts a function that takes any Model as argument and returns a boolean. It is used to search the cache so commonly used with List() function. For example:
lsList := &[]LogicalSwitch{} err := ovs.WhereCache( func(ls *LogicalSwitch) bool { return strings.HasPrefix(ls.Name, "ext_") }).List(lsList)
Server side operations can be executed using WhereCache() conditions but it's not recommended. For each matching cache element, an operation will be created matching on the "_uuid" column. The number of operations can be quite large depending on the cache size and the provided function. Most likely there is a way to express the same condition using Where() or WhereAll() which will be more efficient.
Get ¶
Get() operation is a simple operation capable of retrieving one Model based on some of its indexes. E.g:
ls := &LogicalSwitch{UUID:"myUUID"} err := ovs.Get(ls) fmt.Printf("Name of the switch is: &s", ls.Name)
List ¶
List() searches the cache and populates a slice of Models. It can be used directly or using WhereCache()
lsList := &[]LogicalSwitch{} err := ovs.List(lsList) // List all elements err := ovs.WhereCache( func(ls *LogicalSwitch) bool { return strings.HasPrefix(ls.Name, "ext_") }).List(lsList)
Create ¶
Create returns a list of operations to create the models provided. E.g:
ops, err := ovs.Create(&LogicalSwitch{Name:"foo")}, &LogicalSwitch{Name:"bar"})
Update Update returns a list of operations to update the matching rows to match the values of the provided model. E.g:
ls := &LogicalSwitch{ExternalIDs: map[string]string {"foo": "bar"}} ops, err := ovs.Where(...).Update(&ls, &ls.ExternalIDs}
Mutate ¶
Mutate returns a list of operations needed to mutate the matching rows as described by the list of Mutation objects. E.g:
ls := &LogicalSwitch{} ops, err := ovs.Where(...).Mutate(&ls, client.Mutation { Field: &ls.Config, Mutator: ovsdb.MutateOperationInsert, Value: map[string]string{"foo":"bar"}, })
Delete ¶
Delete returns a list of operations needed to delete the matching rows. E.g:
ops, err := ovs.Where(...).Delete()
Index ¶
Constants ¶
const ( SSL = "ssl" TCP = "tcp" UNIX = "unix" )
Constants defined for libovsdb
Variables ¶
var ErrNotConnected = errors.New("not connected")
ErrNotConnected is an error returned when the client is not connected
var ErrNotFound = errors.New("object not found")
ErrNotFound is used to inform the object or table was not found in the cache
Functions ¶
This section is empty.
Types ¶
type API ¶
type API interface { // List populates a slice of Models objects based on their type // The function parameter must be a pointer to a slice of Models // If the slice is null, the entire cache will be copied into the slice // If it has a capacity != 0, only 'capacity' elements will be filled in List(result interface{}) error // Create a Conditional API from a Function that is used to filter cached data // The function must accept a Model implementation and return a boolean. E.g: // ConditionFromFunc(func(l *LogicalSwitch) bool { return l.Enabled }) WhereCache(predicate interface{}) ConditionalAPI // Create a ConditionalAPI from a Model's index data or a list of Conditions // where operations apply to elements that match any of the conditions // If no condition is given, it will match the values provided in model.Model according // to the database index. Where(model.Model, ...model.Condition) ConditionalAPI // Create a ConditionalAPI from a Model's index data or a list of Conditions // where operations apply to elements that match all the conditions WhereAll(model.Model, ...model.Condition) ConditionalAPI // Get retrieves a model from the cache // The way the object will be fetch depends on the data contained in the // provided model and the indexes defined in the associated schema // For more complex ways of searching for elements in the cache, the // preferred way is Where({condition}).List() Get(model.Model) error // Create returns the operation needed to add the model(s) to the Database // Only fields with non-default values will be added to the transaction // If the field associated with column "_uuid" has some content, it will be // treated as named-uuid Create(...model.Model) ([]ovsdb.Operation, error) }
API defines basic operations to interact with the database
type Client ¶ added in v0.6.0
type Client interface { Connect(context.Context) error Disconnect() Close() Schema() *ovsdb.DatabaseSchema Cache() *cache.TableCache SetOption(Option) error Connected() bool DisconnectNotify() chan struct{} Echo() error Transact(...ovsdb.Operation) ([]ovsdb.OperationResult, error) Monitor(...TableMonitor) (string, error) MonitorAll() (string, error) MonitorCancel(id string) error NewTableMonitor(m model.Model, fields ...interface{}) TableMonitor API }
Client represents an OVSDB Client Connection It provides all the necessary functionality to Connect to a server, perform transactions, and build your own replica of the database with Monitor or MonitorAll. It also provides a Cache that is populated from OVSDB update notifications.
func NewOVSDBClient ¶ added in v0.6.0
NewOVSDBClient creates a new OVSDB Client with the provided database model. The client can be configured using one or more Option(s), like WithTLSConfig. If no WithEndpoint option is supplied, the default of unix:/var/run/openvswitch/ovsdb.sock is used
type Conditional ¶ added in v0.4.0
type Conditional interface { // Generate returns a list of lists of conditions to be used in Operations // Each element in the (outer) list corresponds to an operation Generate() ([][]ovsdb.Condition, error) // matches returns true if a model matches the condition Matches(m model.Model) (bool, error) // returns the table that this condition is associated with Table() string }
Conditional is the interface used by the ConditionalAPI to match on cache objects and generate ovsdb conditions
type ConditionalAPI ¶
type ConditionalAPI interface { // List uses the condition to search on the cache and populates // the slice of Models objects based on their type List(result interface{}) error // Mutate returns the operations needed to perform the mutation specified // By the model and the list of Mutation objects // Depending on the Condition, it might return one or many operations Mutate(model.Model, ...model.Mutation) ([]ovsdb.Operation, error) // Update returns the operations needed to update any number of rows according // to the data in the given model. // By default, all the non-default values contained in model will be updated. // Optional fields can be passed (pointer to fields in the model) to select the // the fields to be updated Update(model.Model, ...interface{}) ([]ovsdb.Operation, error) // Delete returns the Operations needed to delete the models selected via the condition Delete() ([]ovsdb.Operation, error) }
ConditionalAPI is an interface used to perform operations that require / use Conditions
type ErrWrongType ¶ added in v0.4.0
type ErrWrongType struct {
// contains filtered or unexported fields
}
ErrWrongType is used to report the user provided parameter has the wrong type
func (*ErrWrongType) Error ¶ added in v0.4.0
func (e *ErrWrongType) Error() string
type Option ¶ added in v0.4.0
type Option func(o *options) error
func WithEndpoint ¶ added in v0.4.0
WithEndpoint sets the endpoint to be used by the client It can be used multiple times, and the first endpoint that successfully connects will be used. Endpoints are specified in OVSDB Connection Format For more details, see the ovsdb(7) man page
func WithReconnect ¶ added in v0.6.0
WithReconnect tells the client to automatically reconnect when disconnected. The timeout is used to construct the context on each call to Connect, while backoff dicates the backoff algorithm to use
func WithTLSConfig ¶ added in v0.4.0
WithTLSConfig sets the tls.Config for use by the client
type TableMonitor ¶ added in v0.6.0
type TableMonitor struct { // Table is the table to be monitored Table string // Fields are the fields in the model to monitor // If none are supplied, all fields will be used Fields []interface{} // Error will contain any errors caught in the creation of a TableMonitor Error error }
TableMonitor is a table to be monitored