Skip to content

Commit

Permalink
feat(agentctl): Add config get/update commands (#1709)
Browse files Browse the repository at this point in the history
  • Loading branch information
ondrej-fabry committed Aug 27, 2020
1 parent e90a0ef commit 7707f36
Show file tree
Hide file tree
Showing 32 changed files with 783 additions and 327 deletions.
8 changes: 6 additions & 2 deletions client/client_api.go
Expand Up @@ -26,8 +26,12 @@ type ModelInfo = generic.ModelDetail

type StateItem = generic.StateItem

// ConfigClient defines the client-side interface for config.
type ConfigClient interface {
// ConfigClient ...
// Deprecated: use GenericClient instead
type ConfigClient = GenericClient

// GenericClient is the client-side interface for generic handler.
type GenericClient interface {
// KnownModels retrieves list of known modules.
KnownModels(class string) ([]*ModelInfo, error)

Expand Down
21 changes: 6 additions & 15 deletions cmd/agentctl/api/types/client.go
Expand Up @@ -14,22 +14,9 @@

package types

type Model struct {
Name string
Class string
Module string
Type string
Version string
KeyPrefix string
NameTemplate string `json:",omitempty"`
ProtoName string
ProtoFile string `json:",omitempty"`
GoType string `json:",omitempty"`
PkgPath string `json:",omitempty"`
}

type ModelListOptions struct {
Class string
Class string
Module string
}

type SchedulerDumpOptions struct {
Expand All @@ -45,3 +32,7 @@ type SchedulerResyncOptions struct {
Retry bool
Verbose bool
}

type SchedulerHistoryOptions struct {
Count int
}
23 changes: 18 additions & 5 deletions cmd/agentctl/api/types/types.go
Expand Up @@ -26,22 +26,35 @@ type Version struct {
Version string
GitCommit string
GitBranch string

BuildUser string
BuildHost string
BuildTime int64

GoVersion string
OS string
Arch string
}

// Ping contains response of Engine API:
// GET "/_ping"
type Ping struct {
APIVersion string
OSType string
}

type Logger struct {
Logger string `json:"logger,omitempty"`
Logger string
Level string `json:"level,omitempty"`
}

// Model provides info about registered model.
type Model struct {
Name string
Class string
Module string
Type string
Version string
KeyPrefix string
NameTemplate string `json:",omitempty"`
ProtoName string
ProtoFile string `json:",omitempty"`
GoType string `json:",omitempty"`
PkgPath string `json:",omitempty"`
}
16 changes: 5 additions & 11 deletions cmd/agentctl/cli/cli.go
Expand Up @@ -147,22 +147,19 @@ func (cli *AgentCli) Initialize(opts *ClientOptions, ops ...InitializeOpt) error
return err
}
}

if opts.Debug {
debug.Enable()
SetLogLevel("debug")
} else {
SetLogLevel(opts.LogLevel)
}

cfg, err := MakeConfig()
if err != nil {
return err
}
if opts.Debug {
logging.Debug(cfg.DebugOutput())
}

if cli.client == nil {
clientOptions := buildClientOptions(cfg)
cli.client, err = client.NewClientWithOpts(clientOptions...)
Expand All @@ -189,7 +186,6 @@ func buildClientOptions(cfg *Config) []client.Opt {
client.WithEtcdEndpoints(cfg.EtcdEndpoints),
client.WithEtcdDialTimeout(cfg.EtcdDialTimeout),
}

if cfg.ShouldUseSecureGRPC() {
clientOpts = append(clientOpts, client.WithGrpcTLS(
cfg.GRPCSecure.CertFile,
Expand All @@ -214,26 +210,24 @@ func buildClientOptions(cfg *Config) []client.Opt {
cfg.KVDBSecure.SkipVerify,
))
}

return clientOpts
}

func (cli *AgentCli) initializeFromClient() {
logging.Debugf("initializeFromClient (DefaultVersion: %v)", cli.DefaultVersion())

ping, err := cli.client.Ping(context.Background())
version, err := cli.client.AgentVersion(context.Background())
if err != nil {
// Default to true if we fail to connect to daemon
cli.serverInfo = ServerInfo{}

if ping.APIVersion != "" {
cli.client.NegotiateAPIVersionPing(ping)
if version != nil && version.APIVersion != "" {
cli.client.NegotiateAPIVersionPing(version)
}
return
}

cli.serverInfo = ServerInfo{
OSType: ping.OSType,
OSType: version.OSType,
}
cli.client.NegotiateAPIVersionPing(ping)
cli.client.NegotiateAPIVersionPing(version)
}
2 changes: 0 additions & 2 deletions cmd/agentctl/cli/flags.go
Expand Up @@ -84,13 +84,11 @@ func SetLogLevel(logLevel string) {
logging.DefaultLogger.SetLevel(logging.WarnLevel)
return
}

lvl, err := logrus.ParseLevel(logLevel)
if err != nil {
fmt.Fprintf(os.Stderr, "Unable to parse logging level: %s\n", logLevel)
os.Exit(1)
}

logrus.SetLevel(lvl)
logging.DefaultLogger.SetLevel(logging.ParseLogLevel(logLevel))
}
9 changes: 6 additions & 3 deletions cmd/agentctl/client/api.go
Expand Up @@ -12,6 +12,7 @@ import (
"go.ligato.io/vpp-agent/v3/client"
"go.ligato.io/vpp-agent/v3/cmd/agentctl/api/types"
"go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api"
"go.ligato.io/vpp-agent/v3/proto/ligato/configurator"
"go.ligato.io/vpp-agent/v3/proto/ligato/kvscheduler"
)

Expand All @@ -23,7 +24,8 @@ type APIClient interface {
VppAPIClient
MetricsAPIClient

ConfigClient() (client.ConfigClient, error)
GenericClient() (client.GenericClient, error)
ConfiguratorClient() (configurator.ConfiguratorServiceClient, error)

AgentHost() string
Version() string
Expand All @@ -32,14 +34,13 @@ type APIClient interface {
HTTPClient() *http.Client
AgentVersion(ctx context.Context) (*types.Version, error)
NegotiateAPIVersion(ctx context.Context)
NegotiateAPIVersionPing(types.Ping)
NegotiateAPIVersionPing(version *types.Version)
Close() error
}

// InfraAPIClient defines API client methods for the system
type InfraAPIClient interface {
Status(ctx context.Context) (*probe.ExposedStatus, error)
Ping(ctx context.Context) (types.Ping, error)
LoggerList(ctx context.Context) ([]types.Logger, error)
LoggerSet(ctx context.Context, logger, level string) error
}
Expand All @@ -54,11 +55,13 @@ type SchedulerAPIClient interface {
SchedulerDump(ctx context.Context, opts types.SchedulerDumpOptions) ([]api.KVWithMetadata, error)
SchedulerValues(ctx context.Context, opts types.SchedulerValuesOptions) ([]*kvscheduler.BaseValueStatus, error)
SchedulerResync(ctx context.Context, opts types.SchedulerResyncOptions) (*api.RecordedTxn, error)
SchedulerHistory(ctx context.Context, opts types.SchedulerHistoryOptions) (api.RecordedTxns, error)
}

// VppAPIClient defines API client methods for the VPP
type VppAPIClient interface {
VppRunCli(ctx context.Context, cmd string) (reply string, err error)
VppGetStats(ctx context.Context, typ string) error
}

type MetricsAPIClient interface {
Expand Down
37 changes: 17 additions & 20 deletions cmd/agentctl/client/client.go
Expand Up @@ -28,19 +28,19 @@ import (

"github.com/coreos/etcd/clientv3"
"github.com/docker/docker/api/types/versions"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"

"go.ligato.io/cn-infra/v2/db/keyval"
"go.ligato.io/cn-infra/v2/db/keyval/etcd"
"go.ligato.io/cn-infra/v2/logging"
"go.ligato.io/cn-infra/v2/logging/logrus"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"

"go.ligato.io/vpp-agent/v3/client"
"go.ligato.io/vpp-agent/v3/client/remoteclient"
"go.ligato.io/vpp-agent/v3/cmd/agentctl/api"
"go.ligato.io/vpp-agent/v3/cmd/agentctl/api/types"
"go.ligato.io/vpp-agent/v3/pkg/debug"
"go.ligato.io/vpp-agent/v3/proto/ligato/configurator"
)

const (
Expand Down Expand Up @@ -107,16 +107,13 @@ func NewClientWithOpts(ops ...Opt) (*Client, error) {
grpcPort: DefaultPortGRPC,
httpPort: DefaultPortHTTP,
}

for _, op := range ops {
if err := op(c); err != nil {
return nil, err
}
}

c.grpcAddr = net.JoinHostPort(c.host, strconv.Itoa(c.grpcPort))
c.httpAddr = net.JoinHostPort(c.host, strconv.Itoa(c.httpPort))

return c, nil
}

Expand Down Expand Up @@ -155,15 +152,23 @@ func (c *Client) GRPCConn() (*grpc.ClientConn, error) {
return c.grpcClient, nil
}

// ConfigClient returns "remoteclient" with gRPC connection.
func (c *Client) ConfigClient() (client.ConfigClient, error) {
func (c *Client) GenericClient() (client.GenericClient, error) {
conn, err := c.GRPCConn()
if err != nil {
return nil, err
}
return remoteclient.NewClientGRPC(conn), nil
}

// ConfiguratorClient returns "confi" with gRPC connection.
func (c *Client) ConfiguratorClient() (configurator.ConfiguratorServiceClient, error) {
conn, err := c.GRPCConn()
if err != nil {
return nil, err
}
return configurator.NewConfiguratorServiceClient(conn), nil
}

// HTTPClient returns configured HTTP client.
func (c *Client) HTTPClient() *http.Client {
if c.httpClient == nil {
Expand Down Expand Up @@ -231,35 +236,32 @@ func (c *Client) getAPIPath(ctx context.Context, p string, query url.Values) str

func (c *Client) NegotiateAPIVersion(ctx context.Context) {
if !c.manualOverride {
ping, _ := c.Ping(ctx)
c.negotiateAPIVersionPing(ping)
version, _ := c.AgentVersion(ctx)
c.negotiateAPIVersionPing(version)
}
}

func (c *Client) NegotiateAPIVersionPing(p types.Ping) {
func (c *Client) NegotiateAPIVersionPing(p *types.Version) {
if !c.manualOverride {
c.negotiateAPIVersionPing(p)
}
}

// negotiateAPIVersionPing queries the API and updates the version to match the
// API version. Any errors are silently ignored.
func (c *Client) negotiateAPIVersionPing(p types.Ping) {
func (c *Client) negotiateAPIVersionPing(p *types.Version) {
// try the latest version before versioning headers existed
if p.APIVersion == "" {
p.APIVersion = "0.1"
}

// if the client is not initialized with a version, start with the latest supported version
if c.version == "" {
c.version = api.DefaultVersion
}

// if server version is lower than the client version, downgrade
if versions.LessThan(p.APIVersion, c.version) {
c.version = p.APIVersion
}

// Store the results, so that automatic API version negotiation (if enabled)
// won't be performed on the next request.
if c.negotiateVersion {
Expand All @@ -272,9 +274,7 @@ func connectGrpc(addr string, tc *tls.Config) (*grpc.ClientConn, error) {
if tc != nil {
dialOpt = grpc.WithTransportCredentials(credentials.NewTLS(tc))
}

logging.Debugf("dialing grpc address: %v", addr)

return grpc.Dial(addr, dialOpt)
}

Expand All @@ -285,12 +285,10 @@ func connectEtcd(endpoints []string, dialTimeout time.Duration, tc *tls.Config)
} else {
log.SetLevel(logging.WarnLevel)
}

dt := defaultEtcdDialTimeout
if dialTimeout != 0 {
dt = dialTimeout
}

cfg := etcd.ClientConfig{
Config: &clientv3.Config{
Endpoints: endpoints,
Expand All @@ -299,7 +297,6 @@ func connectEtcd(endpoints []string, dialTimeout time.Duration, tc *tls.Config)
},
OpTimeout: defaultEtcdOpTimeout,
}

kvdb, err := etcd.NewEtcdConnectionWithBytes(cfg, log)
if err != nil {
return nil, err
Expand Down

0 comments on commit 7707f36

Please sign in to comment.