Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add config status publishing for config items #1364

Merged
merged 1 commit into from
Jun 3, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't it redundant creating aliases with the same name as original types?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These will be defined as new types later and the API won't have to change for the rest of the code.


// 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)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You could remove all this clutter.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a clutter. This is actually how the example will work after some upcoming changes.

This example will most likely ask user to pick client implementation used for configuring agent. This should demonstrate that the client API can be kept exactly same for all client implementations (local, remote grpc, remote kvdb...)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then I would comment it with a little explanation so it does not look like forgotten commented code, for example:

// choose client implementation (remote, local, ...)

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

// localclient
//demonstrateClient(client.LocalClient)	

...

plus time.Sleep() where needed

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The localclient is not fully supported. I will un-comment this and ask for user input to pick implementation when all are ready and fully implemented.


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