blob: 4dd5e2e49cb95938be4166d83258ad328c8d8589 [file] [log] [blame]
Zack Williamse940c7a2019-08-21 14:25:39 -07001/*
2 * Copyright 2019-present Ciena Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package commands
17
18import (
19 "context"
20 "encoding/json"
Scott Baker9173ed82020-05-19 08:30:12 -070021 "github.com/golang/protobuf/ptypes/empty"
Zack Williamse940c7a2019-08-21 14:25:39 -070022 flags "github.com/jessevdk/go-flags"
Scott Baker2b0ad652019-08-21 14:57:07 -070023 "github.com/opencord/voltctl/internal/pkg/cli/version"
24 "github.com/opencord/voltctl/pkg/format"
Scott Baker9173ed82020-05-19 08:30:12 -070025 "github.com/opencord/voltha-protos/v3/go/voltha"
Zack Williamse940c7a2019-08-21 14:25:39 -070026 "strings"
27)
28
29type VersionDetails struct {
30 Version string `json:"version"`
31 GoVersion string `json:"goversion"`
32 VcsRef string `json:"gitcommit"`
33 VcsDirty string `json:"gitdirty"`
34 BuildTime string `json:"buildtime"`
35 Os string `json:"os"`
36 Arch string `json:"arch"`
37}
38
39type VersionOutput struct {
40 Client VersionDetails `json:"client"`
41 Cluster VersionDetails `json:"cluster"`
42}
43
44type VersionOpts struct {
45 OutputOptions
46 ClientOnly bool `long:"clientonly" description:"Display only client version information"`
47}
48
49var versionOpts = VersionOpts{}
50
51var versionInfo = VersionOutput{
52 Client: VersionDetails{
53 Version: version.Version,
54 GoVersion: version.GoVersion,
55 VcsRef: version.VcsRef,
56 VcsDirty: version.VcsDirty,
57 Os: version.Os,
58 Arch: version.Arch,
59 BuildTime: version.BuildTime,
60 },
61 Cluster: VersionDetails{
62 Version: "unknown-version",
63 GoVersion: "unknown-goversion",
64 VcsRef: "unknown-vcsref",
65 VcsDirty: "unknown-vcsdirty",
66 Os: "unknown-os",
67 Arch: "unknown-arch",
68 BuildTime: "unknown-buildtime",
69 },
70}
71
72func RegisterVersionCommands(parent *flags.Parser) {
73 _, err := parent.AddCommand("version", "display version", "Display client and server version", &versionOpts)
74 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +000075 Error.Fatalf("Unable to register version command: %s", err.Error())
Zack Williamse940c7a2019-08-21 14:25:39 -070076 }
77}
78
79const ClientOnlyFormat = `Client:
80 Version {{.Version}}
81 Go version: {{.GoVersion}}
82 Vcs reference: {{.VcsRef}}
83 Vcs dirty: {{.VcsDirty}}
84 Built: {{.BuildTime}}
85 OS/Arch: {{.Os}}/{{.Arch}}
86`
87
88const DefaultFormat = `Client:
89 Version {{.Client.Version}}
90 Go version: {{.Client.GoVersion}}
91 Vcs reference: {{.Client.VcsRef}}
92 Vcs dirty: {{.Client.VcsDirty}}
93 Built: {{.Client.BuildTime}}
94 OS/Arch: {{.Client.Os}}/{{.Client.Arch}}
95
96Cluster:
97 Version {{.Cluster.Version}}
98 Go version: {{.Cluster.GoVersion}}
99 Vcs feference: {{.Cluster.VcsRef}}
100 Vcs dirty: {{.Cluster.VcsDirty}}
101 Built: {{.Cluster.BuildTime}}
102 OS/Arch: {{.Cluster.Os}}/{{.Cluster.Arch}}
103`
104
105func (options *VersionOpts) clientOnlyVersion(args []string) error {
106 outputFormat := CharReplacer.Replace(options.Format)
107 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000108 outputFormat = GetCommandOptionWithDefault("version", "format", ClientOnlyFormat)
Zack Williamse940c7a2019-08-21 14:25:39 -0700109 }
110 if options.Quiet {
111 outputFormat = "{{.Version}}"
112 }
113
114 result := CommandResult{
115 Format: format.Format(outputFormat),
116 OutputAs: toOutputType(options.OutputAs),
117 NameLimit: options.NameLimit,
118 Data: versionInfo.Client,
119 }
120
121 GenerateOutput(&result)
122 return nil
123}
124
125func (options *VersionOpts) Execute(args []string) error {
126 if options.ClientOnly {
127 return options.clientOnlyVersion(args)
128 }
129
130 conn, err := NewConnection()
131 if err != nil {
132 return err
133 }
134 defer conn.Close()
Scott Baker9173ed82020-05-19 08:30:12 -0700135
136 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700137
138 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
139 defer cancel()
140
Scott Baker9173ed82020-05-19 08:30:12 -0700141 voltha, err := client.GetVoltha(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700142 if err != nil {
Scott Baker9173ed82020-05-19 08:30:12 -0700143 return nil
Zack Williamse940c7a2019-08-21 14:25:39 -0700144 }
145
146 info := make(map[string]interface{})
Scott Baker9173ed82020-05-19 08:30:12 -0700147 err = json.Unmarshal([]byte(voltha.Version), &info)
Zack Williamse940c7a2019-08-21 14:25:39 -0700148 if err != nil {
Scott Baker9173ed82020-05-19 08:30:12 -0700149 versionInfo.Cluster.Version = strings.ReplaceAll(voltha.Version, "\n", "")
Zack Williamse940c7a2019-08-21 14:25:39 -0700150 } else {
151 var ok bool
152 if _, ok = info["version"]; ok {
153 versionInfo.Cluster.Version = info["version"].(string)
154 } else {
155 versionInfo.Cluster.Version = "unknown-version"
156 }
157
158 if _, ok = info["goversion"]; ok {
159 versionInfo.Cluster.GoVersion = info["goversion"].(string)
160 } else {
161 versionInfo.Cluster.GoVersion = "unknown-goversion"
162 }
163
164 if _, ok = info["vcsref"]; ok {
165 versionInfo.Cluster.VcsRef = info["vcsref"].(string)
166 } else {
167 versionInfo.Cluster.VcsRef = "unknown-vcsref"
168 }
169
170 if _, ok = info["vcsdirty"]; ok {
171 versionInfo.Cluster.VcsDirty = info["vcsdirty"].(string)
172 } else {
173 versionInfo.Cluster.VcsDirty = "unknown-vcsdirty"
174 }
175
176 if _, ok = info["buildtime"]; ok {
177 versionInfo.Cluster.BuildTime = info["buildtime"].(string)
178 } else {
179 versionInfo.Cluster.BuildTime = "unknown-buildtime"
180 }
181
182 if _, ok = info["os"]; ok {
183 versionInfo.Cluster.Os = info["os"].(string)
184 } else {
185 versionInfo.Cluster.Os = "unknown-os"
186 }
187
188 if _, ok = info["arch"]; ok {
189 versionInfo.Cluster.Arch = info["arch"].(string)
190 } else {
191 versionInfo.Cluster.Arch = "unknown-arch"
192 }
193 }
194
195 outputFormat := CharReplacer.Replace(options.Format)
196 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000197 outputFormat = GetCommandOptionWithDefault("version", "format", DefaultFormat)
Zack Williamse940c7a2019-08-21 14:25:39 -0700198 }
199 if options.Quiet {
200 outputFormat = "{{.Client.Version}}"
201 }
202
203 result := CommandResult{
204 Format: format.Format(outputFormat),
205 OutputAs: toOutputType(options.OutputAs),
206 NameLimit: options.NameLimit,
207 Data: versionInfo,
208 }
209
210 GenerateOutput(&result)
211 return nil
212}