blob: 51f8d01291d6e6ab5afb68b9ae2076fcb61a44f2 [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 "encoding/json"
21 "fmt"
Scott Bakerce11c492019-07-30 15:53:34 -070022 "github.com/opencord/cordctl/internal/pkg/config"
23 corderrors "github.com/opencord/cordctl/internal/pkg/error"
Scott Baker28a39562019-07-12 09:34:15 -070024 "github.com/opencord/cordctl/pkg/format"
25 "github.com/opencord/cordctl/pkg/order"
Scott Baker2c0ebda2019-05-06 16:55:47 -070026 "google.golang.org/grpc"
27 "gopkg.in/yaml.v2"
Scott Baker14c8f182019-05-22 18:05:29 -070028 "io"
Scott Baker2c0ebda2019-05-06 16:55:47 -070029 "os"
30 "strings"
Scott Baker2c0ebda2019-05-06 16:55:47 -070031)
32
33type OutputType uint8
34
35const (
36 OUTPUT_TABLE OutputType = iota
37 OUTPUT_JSON
38 OUTPUT_YAML
Scott Baker867aa302019-06-19 13:18:45 -070039
40 CORE_VERSION_CONSTRAINT = ">= 3, < 4" // Support XOS major version 3
Scott Baker2c0ebda2019-05-06 16:55:47 -070041)
42
Scott Baker14c8f182019-05-22 18:05:29 -070043// Make it easy to override output stream for testing
44var OutputStream io.Writer = os.Stdout
45
Scott Baker2c0ebda2019-05-06 16:55:47 -070046var CharReplacer = strings.NewReplacer("\\t", "\t", "\\n", "\n")
47
Scott Baker2c0ebda2019-05-06 16:55:47 -070048type OutputOptions struct {
49 Format string `long:"format" value-name:"FORMAT" default:"" description:"Format to use to output structured data"`
50 Quiet bool `short:"q" long:"quiet" description:"Output only the IDs of the objects"`
51 OutputAs string `short:"o" long:"outputas" default:"table" choice:"table" choice:"json" choice:"yaml" description:"Type of output to generate"`
52}
53
Scott Bakera00418a2019-06-03 16:15:28 -070054type ListOutputOptions struct {
55 OutputOptions
56 OrderBy string `short:"r" long:"orderby" default:"" description:"Specify the sort order of the results"`
57}
58
Scott Baker2c0ebda2019-05-06 16:55:47 -070059func toOutputType(in string) OutputType {
60 switch in {
61 case "table":
62 fallthrough
63 default:
64 return OUTPUT_TABLE
65 case "json":
66 return OUTPUT_JSON
67 case "yaml":
68 return OUTPUT_YAML
69 }
70}
71
72type CommandResult struct {
73 Format format.Format
Scott Bakera00418a2019-06-03 16:15:28 -070074 OrderBy string
Scott Baker2c0ebda2019-05-06 16:55:47 -070075 OutputAs OutputType
76 Data interface{}
77}
78
Scott Baker63ce82e2019-05-15 09:01:42 -070079func NewConnection() (*grpc.ClientConn, error) {
Scott Bakerce11c492019-07-30 15:53:34 -070080 config.ProcessGlobalOptions()
81 clientConn, err := grpc.Dial(config.GlobalConfig.Server, grpc.WithInsecure())
82 return clientConn, corderrors.RpcErrorToCordError(err)
Scott Baker2c0ebda2019-05-06 16:55:47 -070083}
84
85func GenerateOutput(result *CommandResult) {
86 if result != nil && result.Data != nil {
Scott Bakera00418a2019-06-03 16:15:28 -070087 data := result.Data
88 if result.OrderBy != "" {
89 s, err := order.Parse(result.OrderBy)
90 if err != nil {
91 panic(err)
92 }
93 data, err = s.Process(data)
94 if err != nil {
95 panic(err)
96 }
97 }
Scott Baker2c0ebda2019-05-06 16:55:47 -070098 if result.OutputAs == OUTPUT_TABLE {
99 tableFormat := format.Format(result.Format)
Scott Bakera00418a2019-06-03 16:15:28 -0700100 tableFormat.Execute(OutputStream, true, data)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700101 } else if result.OutputAs == OUTPUT_JSON {
Scott Bakera00418a2019-06-03 16:15:28 -0700102 asJson, err := json.Marshal(&data)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700103 if err != nil {
104 panic(err)
105 }
Scott Baker14c8f182019-05-22 18:05:29 -0700106 fmt.Fprintf(OutputStream, "%s", asJson)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700107 } else if result.OutputAs == OUTPUT_YAML {
Scott Bakera00418a2019-06-03 16:15:28 -0700108 asYaml, err := yaml.Marshal(&data)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700109 if err != nil {
110 panic(err)
111 }
Scott Baker14c8f182019-05-22 18:05:29 -0700112 fmt.Fprintf(OutputStream, "%s", asYaml)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700113 }
114 }
115}
Scott Baker5281d002019-05-16 10:45:26 -0700116
117// Applies common output options to format and generate output
118func FormatAndGenerateOutput(options *OutputOptions, default_format string, quiet_format string, data interface{}) {
119 outputFormat := CharReplacer.Replace(options.Format)
120 if outputFormat == "" {
121 outputFormat = default_format
122 }
Scott Baker175cb402019-05-17 16:13:06 -0700123 if options.Quiet {
Scott Baker5281d002019-05-16 10:45:26 -0700124 outputFormat = quiet_format
125 }
126
127 result := CommandResult{
128 Format: format.Format(outputFormat),
129 OutputAs: toOutputType(options.OutputAs),
130 Data: data,
131 }
132
133 GenerateOutput(&result)
134}
Scott Bakera00418a2019-06-03 16:15:28 -0700135
136// Applies common output options to format and generate output
137func FormatAndGenerateListOutput(options *ListOutputOptions, default_format string, quiet_format string, data interface{}) {
138 outputFormat := CharReplacer.Replace(options.Format)
139 if outputFormat == "" {
140 outputFormat = default_format
141 }
142 if options.Quiet {
143 outputFormat = quiet_format
144 }
145
146 result := CommandResult{
147 Format: format.Format(outputFormat),
148 OutputAs: toOutputType(options.OutputAs),
149 Data: data,
150 OrderBy: options.OrderBy,
151 }
152
153 GenerateOutput(&result)
154}