blob: 50a50dc971bdc8787a979d2fb21f31e475863ee4 [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
39)
40
Scott Baker14c8f182019-05-22 18:05:29 -070041// Make it easy to override output stream for testing
42var OutputStream io.Writer = os.Stdout
43
Scott Baker2c0ebda2019-05-06 16:55:47 -070044var CharReplacer = strings.NewReplacer("\\t", "\t", "\\n", "\n")
45
Scott Baker2c0ebda2019-05-06 16:55:47 -070046type OutputOptions struct {
47 Format string `long:"format" value-name:"FORMAT" default:"" description:"Format to use to output structured data"`
48 Quiet bool `short:"q" long:"quiet" description:"Output only the IDs of the objects"`
49 OutputAs string `short:"o" long:"outputas" default:"table" choice:"table" choice:"json" choice:"yaml" description:"Type of output to generate"`
50}
51
Scott Bakera00418a2019-06-03 16:15:28 -070052type ListOutputOptions struct {
53 OutputOptions
54 OrderBy string `short:"r" long:"orderby" default:"" description:"Specify the sort order of the results"`
55}
56
Scott Baker2c0ebda2019-05-06 16:55:47 -070057func toOutputType(in string) OutputType {
58 switch in {
59 case "table":
60 fallthrough
61 default:
62 return OUTPUT_TABLE
63 case "json":
64 return OUTPUT_JSON
65 case "yaml":
66 return OUTPUT_YAML
67 }
68}
69
70type CommandResult struct {
71 Format format.Format
Scott Bakera00418a2019-06-03 16:15:28 -070072 OrderBy string
Scott Baker2c0ebda2019-05-06 16:55:47 -070073 OutputAs OutputType
74 Data interface{}
75}
76
Scott Baker63ce82e2019-05-15 09:01:42 -070077func NewConnection() (*grpc.ClientConn, error) {
Scott Bakerce11c492019-07-30 15:53:34 -070078 config.ProcessGlobalOptions()
79 clientConn, err := grpc.Dial(config.GlobalConfig.Server, grpc.WithInsecure())
80 return clientConn, corderrors.RpcErrorToCordError(err)
Scott Baker2c0ebda2019-05-06 16:55:47 -070081}
82
83func GenerateOutput(result *CommandResult) {
84 if result != nil && result.Data != nil {
Scott Bakera00418a2019-06-03 16:15:28 -070085 data := result.Data
86 if result.OrderBy != "" {
87 s, err := order.Parse(result.OrderBy)
88 if err != nil {
89 panic(err)
90 }
91 data, err = s.Process(data)
92 if err != nil {
93 panic(err)
94 }
95 }
Scott Baker2c0ebda2019-05-06 16:55:47 -070096 if result.OutputAs == OUTPUT_TABLE {
97 tableFormat := format.Format(result.Format)
Scott Bakera00418a2019-06-03 16:15:28 -070098 tableFormat.Execute(OutputStream, true, data)
Scott Baker2c0ebda2019-05-06 16:55:47 -070099 } else if result.OutputAs == OUTPUT_JSON {
Scott Bakera00418a2019-06-03 16:15:28 -0700100 asJson, err := json.Marshal(&data)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700101 if err != nil {
102 panic(err)
103 }
Scott Baker14c8f182019-05-22 18:05:29 -0700104 fmt.Fprintf(OutputStream, "%s", asJson)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700105 } else if result.OutputAs == OUTPUT_YAML {
Scott Bakera00418a2019-06-03 16:15:28 -0700106 asYaml, err := yaml.Marshal(&data)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700107 if err != nil {
108 panic(err)
109 }
Scott Baker14c8f182019-05-22 18:05:29 -0700110 fmt.Fprintf(OutputStream, "%s", asYaml)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700111 }
112 }
113}
Scott Baker5281d002019-05-16 10:45:26 -0700114
115// Applies common output options to format and generate output
116func FormatAndGenerateOutput(options *OutputOptions, default_format string, quiet_format string, data interface{}) {
117 outputFormat := CharReplacer.Replace(options.Format)
118 if outputFormat == "" {
119 outputFormat = default_format
120 }
Scott Baker175cb402019-05-17 16:13:06 -0700121 if options.Quiet {
Scott Baker5281d002019-05-16 10:45:26 -0700122 outputFormat = quiet_format
123 }
124
125 result := CommandResult{
126 Format: format.Format(outputFormat),
127 OutputAs: toOutputType(options.OutputAs),
128 Data: data,
129 }
130
131 GenerateOutput(&result)
132}
Scott Bakera00418a2019-06-03 16:15:28 -0700133
134// Applies common output options to format and generate output
135func FormatAndGenerateListOutput(options *ListOutputOptions, default_format string, quiet_format string, data interface{}) {
136 outputFormat := CharReplacer.Replace(options.Format)
137 if outputFormat == "" {
138 outputFormat = default_format
139 }
140 if options.Quiet {
141 outputFormat = quiet_format
142 }
143
144 result := CommandResult{
145 Format: format.Format(outputFormat),
146 OutputAs: toOutputType(options.OutputAs),
147 Data: data,
148 OrderBy: options.OrderBy,
149 }
150
151 GenerateOutput(&result)
152}