blob: 92a7b2c271f022eeacef00366557dec1e50b3915 [file] [log] [blame]
Scott Baker2c0ebda2019-05-06 16:55:47 -07001/*
2 * Portions copyright 2019-present Open Networking Foundation
3 * Original copyright 2019-present Ciena Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package commands
18
19import (
20 "context"
21 "fmt"
22 "github.com/fullstorydev/grpcurl"
Scott Baker2c0ebda2019-05-06 16:55:47 -070023 flags "github.com/jessevdk/go-flags"
24 "github.com/jhump/protoreflect/dynamic"
25 "github.com/opencord/cordctl/format"
Scott Baker6cf525a2019-05-09 12:25:08 -070026 "sort"
Scott Baker2c0ebda2019-05-06 16:55:47 -070027 "strings"
28)
29
30const (
Scott Baker6cf525a2019-05-09 12:25:08 -070031 DEFAULT_MODEL_AVAILABLE_FORMAT = "{{ . }}"
Scott Baker2c0ebda2019-05-06 16:55:47 -070032)
33
34type ModelList struct {
35 OutputOptions
Scott Baker6cf525a2019-05-09 12:25:08 -070036 ShowHidden bool `long:"showhidden" description:"Show hidden fields in default output"`
37 ShowFeedback bool `long:"showfeedback" description:"Show feedback fields in default output"`
38 ShowBookkeeping bool `long:"showbookkeeping" description:"Show bookkeeping fields in default output"`
39 Args struct {
Scott Baker2c0ebda2019-05-06 16:55:47 -070040 ModelName string
41 } `positional-args:"yes" required:"yes"`
42}
43
Scott Baker6cf525a2019-05-09 12:25:08 -070044type ModelAvailable struct {
45 OutputOptions
46}
47
Scott Baker2c0ebda2019-05-06 16:55:47 -070048type ModelOpts struct {
Scott Baker6cf525a2019-05-09 12:25:08 -070049 List ModelList `command:"list"`
50 Available ModelAvailable `command:"available"`
Scott Baker2c0ebda2019-05-06 16:55:47 -070051}
52
53var modelOpts = ModelOpts{}
54
55func RegisterModelCommands(parser *flags.Parser) {
56 parser.AddCommand("model", "model commands", "Commands to query and manipulate XOS models", &modelOpts)
57}
58
Scott Baker6cf525a2019-05-09 12:25:08 -070059func (options *ModelAvailable) Execute(args []string) error {
60 conn, descriptor, err := InitReflectionClient()
Scott Baker2c0ebda2019-05-06 16:55:47 -070061 if err != nil {
62 return err
63 }
Scott Baker6cf525a2019-05-09 12:25:08 -070064
Scott Baker2c0ebda2019-05-06 16:55:47 -070065 defer conn.Close()
66
Scott Baker6cf525a2019-05-09 12:25:08 -070067 models, err := GetModelNames(descriptor)
Scott Baker2c0ebda2019-05-06 16:55:47 -070068 if err != nil {
69 return err
70 }
71
Scott Baker6cf525a2019-05-09 12:25:08 -070072 model_names := []string{}
73 for k := range models {
74 model_names = append(model_names, k)
75 }
76
77 sort.Strings(model_names)
78
79 outputFormat := CharReplacer.Replace(options.Format)
80 if outputFormat == "" {
81 outputFormat = DEFAULT_MODEL_AVAILABLE_FORMAT
82 }
83
84 result := CommandResult{
85 Format: format.Format(outputFormat),
86 OutputAs: toOutputType(options.OutputAs),
87 Data: model_names,
88 }
89
90 GenerateOutput(&result)
91
92 return nil
93}
94
95func (options *ModelList) Execute(args []string) error {
96 conn, descriptor, err := InitReflectionClient()
97 if err != nil {
98 return err
99 }
100
101 defer conn.Close()
102
103 err = CheckModelName(descriptor, options.Args.ModelName)
104 if err != nil {
105 return err
106 }
107
108 method := "xos.xos/List" + options.Args.ModelName
109
Scott Baker2c0ebda2019-05-06 16:55:47 -0700110 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
111 defer cancel()
112
113 headers := GenerateHeaders()
114
115 h := &RpcEventHandler{}
116 err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, headers, h, h.GetParams)
117 if err != nil {
118 return err
119 }
120
121 if h.Status != nil && h.Status.Err() != nil {
122 return h.Status.Err()
123 }
124
125 d, err := dynamic.AsDynamicMessage(h.Response)
126 if err != nil {
127 return err
128 }
129
130 items, err := d.TryGetFieldByName("items")
131 if err != nil {
132 return err
133 }
134
135 field_names := make(map[string]bool)
136 data := make([]map[string]interface{}, len(items.([]interface{})))
137 for i, item := range items.([]interface{}) {
138 val := item.(*dynamic.Message)
139 data[i] = make(map[string]interface{})
140 for _, field_desc := range val.GetKnownFields() {
141 field_name := field_desc.GetName()
Scott Baker2c0ebda2019-05-06 16:55:47 -0700142
143 isGuiHidden := strings.Contains(field_desc.GetFieldOptions().String(), "1005:1")
144 isFeedback := strings.Contains(field_desc.GetFieldOptions().String(), "1006:1")
145 isBookkeeping := strings.Contains(field_desc.GetFieldOptions().String(), "1007:1")
146
147 if isGuiHidden && (!options.ShowHidden) {
148 continue
149 }
150
151 if isFeedback && (!options.ShowFeedback) {
152 continue
153 }
154
Scott Baker6cf525a2019-05-09 12:25:08 -0700155 if isBookkeeping && (!options.ShowBookkeeping) {
Scott Baker2c0ebda2019-05-06 16:55:47 -0700156 continue
157 }
158
159 if field_desc.IsRepeated() {
160 continue
161 }
162
Scott Baker6cf525a2019-05-09 12:25:08 -0700163 data[i][field_name] = val.GetFieldByName(field_name)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700164
165 field_names[field_name] = true
166 }
167 }
168
169 var default_format strings.Builder
170 default_format.WriteString("table")
171 first := true
172 for field_name, _ := range field_names {
173 if first {
174 fmt.Fprintf(&default_format, "{{ .%s }}", field_name)
175 first = false
176 } else {
177 fmt.Fprintf(&default_format, "\t{{ .%s }}", field_name)
178 }
179 }
180
181 outputFormat := CharReplacer.Replace(options.Format)
182 if outputFormat == "" {
183 outputFormat = default_format.String()
184 }
185 if options.Quiet {
186 outputFormat = "{{.Id}}"
187 }
188
189 result := CommandResult{
190 Format: format.Format(outputFormat),
191 OutputAs: toOutputType(options.OutputAs),
192 Data: data,
193 }
194
195 GenerateOutput(&result)
196 return nil
197}