blob: 11067e7ca0c97a81a379f8ffd5d0e2a54977c1cc [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"
23 pbdescriptor "github.com/golang/protobuf/protoc-gen-go/descriptor"
24 flags "github.com/jessevdk/go-flags"
25 "github.com/jhump/protoreflect/dynamic"
26 "github.com/opencord/cordctl/format"
27 "strings"
28)
29
30const (
31 DEFAULT_MODEL_FORMAT = "table{{ .id }}\t{{ .name }}"
32)
33
34type ModelList struct {
35 OutputOptions
36 ShowHidden bool `long:"showhidden" description:"Show hidden fields in default output"`
37 ShowFeedback bool `long:"showfeedback" description:"Show feedback fields in default output"`
38 Args struct {
39 ModelName string
40 } `positional-args:"yes" required:"yes"`
41}
42
43type ModelOpts struct {
44 List ModelList `command:"list"`
45}
46
47var modelOpts = ModelOpts{}
48
49func RegisterModelCommands(parser *flags.Parser) {
50 parser.AddCommand("model", "model commands", "Commands to query and manipulate XOS models", &modelOpts)
51}
52
53func (options *ModelList) Execute(args []string) error {
54
55 conn, err := NewConnection()
56 if err != nil {
57 return err
58 }
59 defer conn.Close()
60
61 // TODO: Validate ModelName
62
63 method_name := "xos.xos/List" + options.Args.ModelName
64
65 descriptor, method, err := GetReflectionMethod(conn, method_name)
66 if err != nil {
67 return err
68 }
69
70 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
71 defer cancel()
72
73 headers := GenerateHeaders()
74
75 h := &RpcEventHandler{}
76 err = grpcurl.InvokeRPC(ctx, descriptor, conn, method, headers, h, h.GetParams)
77 if err != nil {
78 return err
79 }
80
81 if h.Status != nil && h.Status.Err() != nil {
82 return h.Status.Err()
83 }
84
85 d, err := dynamic.AsDynamicMessage(h.Response)
86 if err != nil {
87 return err
88 }
89
90 items, err := d.TryGetFieldByName("items")
91 if err != nil {
92 return err
93 }
94
95 field_names := make(map[string]bool)
96 data := make([]map[string]interface{}, len(items.([]interface{})))
97 for i, item := range items.([]interface{}) {
98 val := item.(*dynamic.Message)
99 data[i] = make(map[string]interface{})
100 for _, field_desc := range val.GetKnownFields() {
101 field_name := field_desc.GetName()
102 field_type := field_desc.GetType()
103
104 isGuiHidden := strings.Contains(field_desc.GetFieldOptions().String(), "1005:1")
105 isFeedback := strings.Contains(field_desc.GetFieldOptions().String(), "1006:1")
106 isBookkeeping := strings.Contains(field_desc.GetFieldOptions().String(), "1007:1")
107
108 if isGuiHidden && (!options.ShowHidden) {
109 continue
110 }
111
112 if isFeedback && (!options.ShowFeedback) {
113 continue
114 }
115
116 if isBookkeeping {
117 continue
118 }
119
120 if field_desc.IsRepeated() {
121 continue
122 }
123
124 switch field_type {
125 case pbdescriptor.FieldDescriptorProto_TYPE_STRING:
126 data[i][field_name] = val.GetFieldByName(field_name).(string)
127 case pbdescriptor.FieldDescriptorProto_TYPE_INT32:
128 data[i][field_name] = val.GetFieldByName(field_name).(int32)
129 case pbdescriptor.FieldDescriptorProto_TYPE_BOOL:
130 data[i][field_name] = val.GetFieldByName(field_name).(bool)
131 // case pbdescriptor.FieldDescriptorProto_TYPE_DOUBLE:
132 // data[i][field_name] = val.GetFieldByName(field_name).(double)
133 }
134
135 field_names[field_name] = true
136 }
137 }
138
139 var default_format strings.Builder
140 default_format.WriteString("table")
141 first := true
142 for field_name, _ := range field_names {
143 if first {
144 fmt.Fprintf(&default_format, "{{ .%s }}", field_name)
145 first = false
146 } else {
147 fmt.Fprintf(&default_format, "\t{{ .%s }}", field_name)
148 }
149 }
150
151 outputFormat := CharReplacer.Replace(options.Format)
152 if outputFormat == "" {
153 outputFormat = default_format.String()
154 }
155 if options.Quiet {
156 outputFormat = "{{.Id}}"
157 }
158
159 result := CommandResult{
160 Format: format.Format(outputFormat),
161 OutputAs: toOutputType(options.OutputAs),
162 Data: data,
163 }
164
165 GenerateOutput(&result)
166 return nil
167}