Skip to content

Commit

Permalink
Add config status publishing for config items (#1364)
Browse files Browse the repository at this point in the history
Signed-off-by: Ondrej Fabry <ofabry@cisco.com>
  • Loading branch information
ondrej-fabry authored Jun 3, 2019
1 parent 25caa2b commit ed09c82
Show file tree
Hide file tree
Showing 13 changed files with 598 additions and 343 deletions.
346 changes: 172 additions & 174 deletions api/genericmanager/genericmanager.pb.go

Large diffs are not rendered by default.

37 changes: 19 additions & 18 deletions api/genericmanager/genericmanager.proto
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ service GenericManager {
// SetConfig is used to update desired configuration.
rpc SetConfig (SetConfigRequest) returns (SetConfigResponse);

// GetConfig is used to readt current configuration.
// GetConfig is used to read the desired configuration.
rpc GetConfig (GetConfigRequest) returns (GetConfigResponse);

// DumpState retrieves the current running state.
// DumpState is used to retrieve the actual running state.
rpc DumpState (DumpStateRequest) returns (DumpStateResponse);

// Subscribe is used for subscribing to events.
Expand All @@ -66,7 +66,7 @@ service GenericManager {
//------------------------------------------------------------------------------

message CapabilitiesRequest {
// TODO: query filters
// TODO: filters
}
message CapabilitiesResponse {
repeated ModelInfo known_models = 1;
Expand All @@ -86,6 +86,9 @@ message SetConfigRequest {
// (this is also known as Full Resync)
bool overwrite_all = 2;
}
message SetConfigResponse {
repeated UpdateResult results = 1;
}

message UpdateItem {
// The item describes item to be updated.
Expand All @@ -95,10 +98,6 @@ message UpdateItem {
map<string, string> labels = 2;
}

message SetConfigResponse {
repeated UpdateResult results = 1;
}

message UpdateResult {
enum Operation {
UNSPECIFIED = 0;
Expand All @@ -118,25 +117,27 @@ message GetConfigRequest {
repeated Item.ID ids = 1;
}
message GetConfigResponse {
message ConfigItem {
Item item = 1;
ItemStatus status = 2;
map<string, string> labels = 3;
}
repeated ConfigItem items = 1;
}

message ConfigItem {
Item item = 1;
ItemStatus status = 2;
map<string, string> labels = 3;
}

//------------------------------------------------------------------------------

message DumpStateRequest {
repeated string keys = 1;
repeated Item.ID ids = 1;
}
message DumpStateResponse {
message StateItem {
Item item = 1;
map<string, string> metadata = 2;
}
repeated StateItem states = 1;
repeated StateItem items = 1;
}

message StateItem {
Item item = 1;
map<string, string> metadata = 2;
}

//------------------------------------------------------------------------------
Expand Down
11 changes: 10 additions & 1 deletion client/client_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@ import (
"context"

"github.com/gogo/protobuf/proto"

api "github.com/ligato/vpp-agent/api/genericmanager"
)

type ModelInfo = api.ModelInfo

type StateItem = api.StateItem

// ConfigClient defines the client-side interface for config.
type ConfigClient interface {
// KnownModels retrieves list of known modules.
KnownModels() ([]api.ModelInfo, error)
KnownModels() ([]ModelInfo, error)

// ChangeRequest returns transaction for changing config.
ChangeRequest() ChangeRequest
Expand All @@ -19,7 +24,11 @@ type ConfigClient interface {
ResyncConfig(items ...proto.Message) error

// GetConfig retrieves current config into dsts.
// TODO: return as list of config items
GetConfig(dsts ...interface{}) error

// DumpState dumps actual running state.
DumpState() ([]*StateItem, error)
}

// ChangeRequest is interface for config change request.
Expand Down
7 changes: 6 additions & 1 deletion client/local_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,10 +61,15 @@ func (c *client) ResyncConfig(items ...proto.Message) error {
}

func (c *client) GetConfig(dsts ...interface{}) error {

// TODO: use dispatcher to get config
return nil
}

func (c *client) DumpState() ([]*api.StateItem, error) {
// TODO: use dispatcher to dump state
return nil, nil
}

func (c *client) ChangeRequest() ChangeRequest {
return &changeRequest{txn: c.txnFactory.NewTxn(false)}
}
Expand Down
35 changes: 30 additions & 5 deletions client/remoteclient/grpc_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,14 @@ func (c *grpcClient) GetConfig(dsts ...interface{}) error {
return err
}

fmt.Printf("GetConfig: %+v\n", resp)
fmt.Printf("grpcClient.GetConfig: received %d items\n", len(resp.Items))
tm := proto.TextMarshaler{
Compact: true,
ExpandAny: true,
}
for _, item := range resp.Items {
fmt.Printf(" - %v\n", tm.Text(item))
}

protos := map[string]proto.Message{}
for _, item := range resp.Items {
Expand All @@ -97,6 +104,26 @@ func (c *grpcClient) GetConfig(dsts ...interface{}) error {
return nil
}

func (c *grpcClient) DumpState() ([]*client.StateItem, error) {
ctx := context.Background()

resp, err := c.remote.DumpState(ctx, &api.DumpStateRequest{})
if err != nil {
return nil, err
}

/*lfmt.Printf("grpcClient.DumpState: received %d items\n", len(resp.States))
tm := proto.TextMarshaler{
Compact: true,
ExpandAny: true,
}
for _, item := range resp.States {
fmt.Printf(" - %v\n", tm.Text(item))
}*/

return resp.GetItems(), nil
}

type setConfigRequest struct {
client api.GenericManagerClient
req *api.SetConfigRequest
Expand Down Expand Up @@ -127,10 +154,8 @@ func (r *setConfigRequest) Delete(items ...proto.Message) client.ChangeRequest {
for _, protoModel := range items {
item, err := models.MarshalItem(protoModel)
if err != nil {
if err != nil {
r.err = err
return r
}
r.err = err
return r
}
r.req.Updates = append(r.req.Updates, &api.UpdateItem{
/*Item: &api.Item{
Expand Down
1 change: 1 addition & 0 deletions cmd/vpp-agent/app/vpp_agent.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func New() *VPPAgent {
redisDataSync,
}
orchestrator.DefaultPlugin.Watcher = watchers
orchestrator.DefaultPlugin.StatusPublisher = writers

ifplugin.DefaultPlugin.Watcher = watchers
ifplugin.DefaultPlugin.NotifyStates = ifStatePub
Expand Down
114 changes: 77 additions & 37 deletions examples/custom_model/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,27 +26,28 @@ import (
"github.com/ligato/cn-infra/agent"
"github.com/ligato/cn-infra/infra"
"github.com/ligato/cn-infra/logging/logrus"
"github.com/ligato/vpp-agent/api/configurator"
"github.com/ligato/vpp-agent/api/genericmanager"
"github.com/ligato/vpp-agent/client"
"github.com/ligato/vpp-agent/client/remoteclient"
"github.com/ligato/vpp-agent/cmd/vpp-agent/app"
"github.com/ligato/vpp-agent/examples/custom_model/pb"
mymodel "github.com/ligato/vpp-agent/examples/custom_model/pb"
"github.com/ligato/vpp-agent/plugins/orchestrator"
"github.com/namsral/flag"
"google.golang.org/grpc"

"github.com/ligato/vpp-agent/api/models/linux"
"github.com/ligato/vpp-agent/api/models/linux/interfaces"
"github.com/ligato/vpp-agent/api/models/linux/l3"
linux_interfaces "github.com/ligato/vpp-agent/api/models/linux/interfaces"
linux_l3 "github.com/ligato/vpp-agent/api/models/linux/l3"
"github.com/ligato/vpp-agent/api/models/vpp"
interfaces "github.com/ligato/vpp-agent/api/models/vpp/interfaces"
"github.com/ligato/vpp-agent/api/models/vpp/l2"
vpp_l2 "github.com/ligato/vpp-agent/api/models/vpp/l2"
)

var (
address = flag.String("address", "172.17.0.2:9111", "address of GRPC server")
address = flag.String("address", "127.0.0.1:9111", "address of GRPC server")
socketType = flag.String("socket-type", "tcp", "socket type [tcp, tcp4, tcp6, unix, unixpacket]")

dialTimeout = time.Second * 2
dialTimeout = time.Second * 3
)

var exampleFinished = make(chan struct{})
Expand All @@ -66,7 +67,7 @@ func main() {
agent.QuitOnClose(exampleFinished),
)
if err := a.Run(); err != nil {
log.Fatal()
log.Fatal(err)
}
}

Expand Down Expand Up @@ -109,12 +110,14 @@ func (p *ExamplePlugin) AfterInit() (err error) {
go func() {
time.Sleep(time.Second)

//c := remoteclient.NewClientGRPC(api.NewGenericManagerClient(conn))
c := client.LocalClient

// remoteclient
c := remoteclient.NewClientGRPC(genericmanager.NewGenericManagerClient(p.conn))
demonstrateClient(c)

time.Sleep(time.Second * 3)
//time.Sleep(time.Second * 3)

// localclient
//demonstrateClient(client.LocalClient)

logrus.DefaultLogger().Info("Closing example")
close(exampleFinished)
Expand All @@ -137,40 +140,50 @@ func (p *ExamplePlugin) Close() error {
}

func demonstrateClient(c client.ConfigClient) {
// ==========================================
tm := proto.TextMarshaler{
Compact: true,
ExpandAny: true,
}
log.SetFlags(log.Lshortfile | log.Lmicroseconds)

// List known models
// ==========================================
fmt.Println("# ==========================================")
fmt.Println("# List known models..")
fmt.Println("# ==========================================")
knownModels, err := c.KnownModels()
if err != nil {
log.Fatalln(err)
log.Println("KnownModels failed:", err)
}
fmt.Printf("Listing %d known models..\n", len(knownModels))
fmt.Printf("listing %d models\n", len(knownModels))
for _, model := range knownModels {
fmt.Printf(" - %v\n", model.String())
}
time.Sleep(time.Second * 3)
time.Sleep(time.Second * 1)

// ==========================================
// Resync config
// ==========================================
fmt.Printf("Requesting config resync..\n")
fmt.Println("# ==========================================")
fmt.Println("# Requesting config resync..")
fmt.Println("# ==========================================")
customModel := &mymodel.MyModel{
Name: "TheModel",
}
err = c.ResyncConfig(
memif1, memif2,
veth1, veth2,
routeX,
routeX, routeCache,
customModel,
)
if err != nil {
log.Fatalln(err)
log.Println("ResyncConfig failed:", err)
}
time.Sleep(time.Second * 5)
time.Sleep(time.Second * 2)

// ==========================================
// Change config
// ==========================================
fmt.Printf("Requesting config change..\n")
fmt.Println("# ==========================================")
fmt.Println("# Requesting config change..")
fmt.Println("# ==========================================")
memif1.Enabled = false
memif1.Mtu = 666

custom := &mymodel.MyModel{
Name: "my1",
Mynum: 33,
Expand All @@ -182,20 +195,35 @@ func demonstrateClient(c client.ConfigClient) {
if err := req.Send(context.Background()); err != nil {
log.Fatalln(err)
}
time.Sleep(time.Second * 5)
time.Sleep(time.Second * 2)

// ==========================================
// Get config
// ==========================================
fmt.Printf("Retrieving config..\n")
data := &configurator.Config{
VppConfig: &vpp.ConfigData{},
LinuxConfig: &linux.ConfigData{},
fmt.Println("# ==========================================")
fmt.Println("# Retrieving config..")
fmt.Println("# ==========================================")
type config struct {
VPP vpp.ConfigData
Linux linux.ConfigData
MyModels []*mymodel.MyModel
}
if err := c.GetConfig(data.VppConfig, data.LinuxConfig); err != nil {
log.Fatalln(err)
var cfg config
if err := c.GetConfig(&cfg.VPP, &cfg.Linux, &cfg); err != nil {
log.Println("GetConfig failed:", err)
}
fmt.Printf("Retrieved config:\n%+v\n", cfg)

// Dump state
fmt.Println("# ==========================================")
fmt.Println("# Dumping state..")
fmt.Println("# ==========================================")
states, err := c.DumpState()
if err != nil {
log.Println("DumpState failed:", err)
}
fmt.Printf("Dumping %d states\n", len(states))
for _, state := range states {
fmt.Printf(" - %v\n", tm.Text(state))
}
fmt.Printf("Retrieved config:\n%+v\n", proto.MarshalTextString(data))
}

// Dialer for unix domain socket
Expand Down Expand Up @@ -286,4 +314,16 @@ var (
GwAddr: "10.10.3.254",
Scope: linux_l3.Route_GLOBAL,
}
routeCache = &linux.Route{
DstNetwork: "10.10.5.0/24",
OutgoingInterface: "if10",
GwAddr: "10.10.5.254",
Scope: linux_l3.Route_GLOBAL,
}
routeBad = &linux.Route{
DstNetwork: "192.168.6.0/24",
OutgoingInterface: "myVETH1",
GwAddr: "10.10.3.2545",
Scope: linux_l3.Route_GLOBAL,
}
)
Loading

0 comments on commit ed09c82

Please sign in to comment.