blob: 1efac082cd4fe24306c27012c463d4c6ad0378d2 [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"
David K. Bainbridge1d946442021-03-19 16:45:52 +000021 "strings"
22
Scott Baker9173ed82020-05-19 08:30:12 -070023 "github.com/golang/protobuf/ptypes/empty"
Zack Williamse940c7a2019-08-21 14:25:39 -070024 flags "github.com/jessevdk/go-flags"
Scott Baker2b0ad652019-08-21 14:57:07 -070025 "github.com/opencord/voltctl/internal/pkg/cli/version"
26 "github.com/opencord/voltctl/pkg/format"
David K. Bainbridgebd6b2882021-08-26 13:31:02 +000027 "github.com/opencord/voltha-protos/v5/go/voltha"
Zack Williamse940c7a2019-08-21 14:25:39 -070028)
29
30type VersionDetails struct {
31 Version string `json:"version"`
32 GoVersion string `json:"goversion"`
33 VcsRef string `json:"gitcommit"`
34 VcsDirty string `json:"gitdirty"`
35 BuildTime string `json:"buildtime"`
36 Os string `json:"os"`
37 Arch string `json:"arch"`
38}
39
40type VersionOutput struct {
41 Client VersionDetails `json:"client"`
42 Cluster VersionDetails `json:"cluster"`
43}
44
45type VersionOpts struct {
46 OutputOptions
47 ClientOnly bool `long:"clientonly" description:"Display only client version information"`
48}
49
50var versionOpts = VersionOpts{}
51
52var versionInfo = VersionOutput{
53 Client: VersionDetails{
54 Version: version.Version,
55 GoVersion: version.GoVersion,
56 VcsRef: version.VcsRef,
57 VcsDirty: version.VcsDirty,
58 Os: version.Os,
59 Arch: version.Arch,
60 BuildTime: version.BuildTime,
61 },
62 Cluster: VersionDetails{
63 Version: "unknown-version",
64 GoVersion: "unknown-goversion",
65 VcsRef: "unknown-vcsref",
66 VcsDirty: "unknown-vcsdirty",
67 Os: "unknown-os",
68 Arch: "unknown-arch",
69 BuildTime: "unknown-buildtime",
70 },
71}
72
73func RegisterVersionCommands(parent *flags.Parser) {
74 _, err := parent.AddCommand("version", "display version", "Display client and server version", &versionOpts)
75 if err != nil {
David Bainbridge0f758d42019-10-26 05:17:48 +000076 Error.Fatalf("Unable to register version command: %s", err.Error())
Zack Williamse940c7a2019-08-21 14:25:39 -070077 }
78}
79
80const ClientOnlyFormat = `Client:
81 Version {{.Version}}
82 Go version: {{.GoVersion}}
83 Vcs reference: {{.VcsRef}}
84 Vcs dirty: {{.VcsDirty}}
85 Built: {{.BuildTime}}
86 OS/Arch: {{.Os}}/{{.Arch}}
87`
88
89const DefaultFormat = `Client:
90 Version {{.Client.Version}}
91 Go version: {{.Client.GoVersion}}
92 Vcs reference: {{.Client.VcsRef}}
93 Vcs dirty: {{.Client.VcsDirty}}
94 Built: {{.Client.BuildTime}}
95 OS/Arch: {{.Client.Os}}/{{.Client.Arch}}
96
97Cluster:
98 Version {{.Cluster.Version}}
99 Go version: {{.Cluster.GoVersion}}
100 Vcs feference: {{.Cluster.VcsRef}}
101 Vcs dirty: {{.Cluster.VcsDirty}}
102 Built: {{.Cluster.BuildTime}}
103 OS/Arch: {{.Cluster.Os}}/{{.Cluster.Arch}}
104`
105
106func (options *VersionOpts) clientOnlyVersion(args []string) error {
107 outputFormat := CharReplacer.Replace(options.Format)
108 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000109 outputFormat = GetCommandOptionWithDefault("version", "format", ClientOnlyFormat)
Zack Williamse940c7a2019-08-21 14:25:39 -0700110 }
111 if options.Quiet {
112 outputFormat = "{{.Version}}"
113 }
114
115 result := CommandResult{
116 Format: format.Format(outputFormat),
117 OutputAs: toOutputType(options.OutputAs),
118 NameLimit: options.NameLimit,
119 Data: versionInfo.Client,
120 }
121
122 GenerateOutput(&result)
123 return nil
124}
125
126func (options *VersionOpts) Execute(args []string) error {
127 if options.ClientOnly {
128 return options.clientOnlyVersion(args)
129 }
130
131 conn, err := NewConnection()
132 if err != nil {
133 return err
134 }
135 defer conn.Close()
Scott Baker9173ed82020-05-19 08:30:12 -0700136
137 client := voltha.NewVolthaServiceClient(conn)
Zack Williamse940c7a2019-08-21 14:25:39 -0700138
David K. Bainbridge9189c632021-03-26 21:52:21 +0000139 ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Current().Grpc.Timeout)
Zack Williamse940c7a2019-08-21 14:25:39 -0700140 defer cancel()
141
Scott Baker9173ed82020-05-19 08:30:12 -0700142 voltha, err := client.GetVoltha(ctx, &empty.Empty{})
Zack Williamse940c7a2019-08-21 14:25:39 -0700143 if err != nil {
David K. Bainbridge1d946442021-03-19 16:45:52 +0000144 return err
Zack Williamse940c7a2019-08-21 14:25:39 -0700145 }
146
147 info := make(map[string]interface{})
Scott Baker9173ed82020-05-19 08:30:12 -0700148 err = json.Unmarshal([]byte(voltha.Version), &info)
Zack Williamse940c7a2019-08-21 14:25:39 -0700149 if err != nil {
Scott Baker9173ed82020-05-19 08:30:12 -0700150 versionInfo.Cluster.Version = strings.ReplaceAll(voltha.Version, "\n", "")
Zack Williamse940c7a2019-08-21 14:25:39 -0700151 } else {
152 var ok bool
153 if _, ok = info["version"]; ok {
154 versionInfo.Cluster.Version = info["version"].(string)
155 } else {
156 versionInfo.Cluster.Version = "unknown-version"
157 }
158
159 if _, ok = info["goversion"]; ok {
160 versionInfo.Cluster.GoVersion = info["goversion"].(string)
161 } else {
162 versionInfo.Cluster.GoVersion = "unknown-goversion"
163 }
164
165 if _, ok = info["vcsref"]; ok {
166 versionInfo.Cluster.VcsRef = info["vcsref"].(string)
167 } else {
168 versionInfo.Cluster.VcsRef = "unknown-vcsref"
169 }
170
171 if _, ok = info["vcsdirty"]; ok {
172 versionInfo.Cluster.VcsDirty = info["vcsdirty"].(string)
173 } else {
174 versionInfo.Cluster.VcsDirty = "unknown-vcsdirty"
175 }
176
177 if _, ok = info["buildtime"]; ok {
178 versionInfo.Cluster.BuildTime = info["buildtime"].(string)
179 } else {
180 versionInfo.Cluster.BuildTime = "unknown-buildtime"
181 }
182
183 if _, ok = info["os"]; ok {
184 versionInfo.Cluster.Os = info["os"].(string)
185 } else {
186 versionInfo.Cluster.Os = "unknown-os"
187 }
188
189 if _, ok = info["arch"]; ok {
190 versionInfo.Cluster.Arch = info["arch"].(string)
191 } else {
192 versionInfo.Cluster.Arch = "unknown-arch"
193 }
194 }
195
196 outputFormat := CharReplacer.Replace(options.Format)
197 if outputFormat == "" {
David Bainbridgea6722342019-10-24 23:55:53 +0000198 outputFormat = GetCommandOptionWithDefault("version", "format", DefaultFormat)
Zack Williamse940c7a2019-08-21 14:25:39 -0700199 }
200 if options.Quiet {
201 outputFormat = "{{.Client.Version}}"
202 }
203
204 result := CommandResult{
205 Format: format.Format(outputFormat),
206 OutputAs: toOutputType(options.OutputAs),
207 NameLimit: options.NameLimit,
208 Data: versionInfo,
209 }
210
211 GenerateOutput(&result)
212 return nil
213}