-
Notifications
You must be signed in to change notification settings - Fork 30
/
watch.go
169 lines (145 loc) · 4.64 KB
/
watch.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
// SPDX-FileCopyrightText: 2020-present Open Networking Foundation <info@opennetworking.org>
//
// SPDX-License-Identifier: Apache-2.0
package topo
import (
"context"
"fmt"
"io"
"os"
topoapi "github.com/onosproject/onos-api/go/onos/topo"
"github.com/onosproject/onos-lib-go/pkg/cli"
"github.com/spf13/cobra"
)
func getWatchEntityCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "entity [id] [args]",
Short: "Watch Entities",
Args: cobra.MaximumNArgs(2),
RunE: runWatchEntityCommand,
}
cmd.Flags().BoolP("no-replay", "r", false, "do not replay existing topo state")
cmd.Flags().Bool("no-headers", false, "disables output headers")
cmd.Flags().BoolP("verbose", "v", false, "verbose output")
cmd.Flags().String("kind", "", "kind query")
cmd.Flags().String("label", "", "label query")
return cmd
}
func getWatchRelationCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "relation <id> [args]",
Short: "Watch Relations",
Args: cobra.MaximumNArgs(2),
RunE: runWatchRelationCommand,
}
cmd.Flags().BoolP("no-replay", "r", false, "do not replay exiting topo state")
cmd.Flags().Bool("no-headers", false, "disables output headers")
cmd.Flags().BoolP("verbose", "v", false, "verbose output")
cmd.Flags().String("kind", "", "kind query")
cmd.Flags().String("label", "", "label query")
return cmd
}
func getWatchKindCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "kind [id] [args]",
Short: "Watch Kinds",
Args: cobra.MaximumNArgs(2),
RunE: runWatchKindCommand,
}
cmd.Flags().BoolP("no-replay", "r", false, "do not replay exiting topo state")
cmd.Flags().Bool("no-headers", false, "disables output headers")
cmd.Flags().BoolP("verbose", "v", false, "verbose output")
cmd.Flags().String("kind", "", "kind query")
cmd.Flags().String("label", "", "label query")
return cmd
}
func getWatchAllCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "all [args]",
Short: "Watch Entities, Relations and Kinds",
RunE: runWatchAllCommand,
}
cmd.Flags().BoolP("no-replay", "r", false, "do not replay exiting topo state")
cmd.Flags().Bool("no-headers", false, "disables output headers")
cmd.Flags().BoolP("verbose", "v", false, "verbose output")
cmd.Flags().String("kind", "", "kind query")
cmd.Flags().String("label", "", "label query")
return cmd
}
func runWatchEntityCommand(cmd *cobra.Command, args []string) error {
return watch(cmd, args, topoapi.Object_ENTITY)
}
func runWatchRelationCommand(cmd *cobra.Command, args []string) error {
return watch(cmd, args, topoapi.Object_RELATION)
}
func runWatchKindCommand(cmd *cobra.Command, args []string) error {
return watch(cmd, args, topoapi.Object_KIND)
}
func runWatchAllCommand(cmd *cobra.Command, args []string) error {
return watch(cmd, args, topoapi.Object_UNSPECIFIED)
}
func watch(cmd *cobra.Command, args []string, objectType topoapi.Object_Type) error {
noHeaders, _ := cmd.Flags().GetBool("no-headers")
noreplay, _ := cmd.Flags().GetBool("noreplay")
verbose, _ := cmd.Flags().GetBool("verbose")
var id topoapi.ID
if len(args) > 0 {
id = topoapi.ID(args[0])
} else {
id = topoapi.NullID
}
filters := compileFilters(cmd, objectType)
conn, err := cli.GetConnection(cmd)
if err != nil {
return err
}
defer conn.Close()
client := topoapi.CreateTopoClient(conn)
req := &topoapi.WatchRequest{
Filters: filters,
Noreplay: noreplay,
}
stream, err := client.Watch(context.Background(), req)
if err != nil {
return err
}
writer := os.Stdout
if !noHeaders {
printHeader(writer, objectType, true, verbose)
}
for {
res, err := stream.Recv()
if err == io.EOF {
break
}
if err != nil {
cli.Output("Error receiving notification : %v", err)
return err
}
event := res.Event
// TODO: Filtering for ID and object type is still client-side; labels and kinds are server-side now
if id == topoapi.NullID || id == event.Object.ID {
if event.Object.Type == topoapi.Object_UNSPECIFIED || objectType == event.Object.Type {
printUpdateType(writer, event.Type, event.Object.Type, verbose)
printObject(writer, event.Object, verbose, false, false)
}
}
}
return nil
}
func printUpdateType(writer io.Writer, eventType topoapi.EventType, objectType topoapi.Object_Type, verbose bool) {
if verbose {
if eventType == topoapi.EventType_NONE {
fmt.Fprintf(writer, "Update Type:\t%s\n", "REPLAY")
} else {
fmt.Fprintf(writer, "Update Type:\t%s\n", eventType)
}
fmt.Fprintf(writer, "Object Type:\t%s\n", objectType)
} else {
if eventType == topoapi.EventType_NONE {
_, _ = fmt.Fprintf(writer, "%-12s\t%-10s\t", "REPLAY", objectType)
} else {
_, _ = fmt.Fprintf(writer, "%-12s\t%-10s\t", eventType, objectType)
}
}
}