blob: 819e82f0db20f39f8959e0144e931ee9a3dcbb06 [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 (
Scott Baker2c0ebda2019-05-06 16:55:47 -070020 "errors"
Scott Baker72efd752019-05-15 13:12:20 -070021 "fmt"
Scott Baker2c0ebda2019-05-06 16:55:47 -070022 flags "github.com/jessevdk/go-flags"
Scott Baker2c0ebda2019-05-06 16:55:47 -070023 "github.com/opencord/cordctl/format"
Scott Baker2c0ebda2019-05-06 16:55:47 -070024 "strings"
25)
26
27const (
28 DEFAULT_TRANSFER_FORMAT = "table{{ .Status }}\t{{ .Checksum }}\t{{ .Chunks }}\t{{ .Bytes }}"
29)
30
31type TransferOutput struct {
32 Status string `json:"status"`
33 Checksum string `json:"checksum"`
34 Chunks int `json:"chunks"`
35 Bytes int `json:"bytes"`
36}
37
38type TransferUpload struct {
39 OutputOptions
40 ChunkSize int `short:"h" long:"chunksize" default:"65536" description:"Host and port"`
41 Args struct {
42 LocalFileName string
43 URI string
44 } `positional-args:"yes" required:"yes"`
45}
46
47type TransferDownload struct {
48 OutputOptions
49 Args struct {
50 URI string
51 LocalFileName string
52 } `positional-args:"yes" required:"yes"`
53}
54
55type TransferOpts struct {
56 Upload TransferUpload `command:"upload"`
57 Download TransferDownload `command:"download"`
58}
59
60var transferOpts = TransferOpts{}
61
62func RegisterTransferCommands(parser *flags.Parser) {
63 parser.AddCommand("transfer", "file transfer commands", "Commands to transfer files to and from XOS", &transferOpts)
64}
65
Scott Baker2c0ebda2019-05-06 16:55:47 -070066/* Command processors */
67
68func (options *TransferUpload) Execute(args []string) error {
69
Scott Baker6cf525a2019-05-09 12:25:08 -070070 conn, descriptor, err := InitReflectionClient()
Scott Baker2c0ebda2019-05-06 16:55:47 -070071 if err != nil {
72 return err
73 }
74 defer conn.Close()
75
76 local_name := options.Args.LocalFileName
77 uri := options.Args.URI
78
Scott Baker6cf525a2019-05-09 12:25:08 -070079 if IsFileUri(local_name) {
80 return errors.New("local_name argument should not be a uri")
Scott Baker2c0ebda2019-05-06 16:55:47 -070081 }
82
Scott Baker6cf525a2019-05-09 12:25:08 -070083 if !IsFileUri(uri) {
84 return errors.New("uri argument should be a file:// uri")
Scott Baker2c0ebda2019-05-06 16:55:47 -070085 }
86
Scott Baker72efd752019-05-15 13:12:20 -070087 h, upload_result, err := UploadFile(conn, descriptor, local_name, uri, options.ChunkSize)
88
89 if upload_result.GetFieldByName("checksum").(string) != h.GetChecksum() {
90 return fmt.Errorf("Checksum mismatch, expected=%s, received=%s",
91 h.GetChecksum(),
92 upload_result.GetFieldByName("checksum").(string))
93 }
Scott Baker2c0ebda2019-05-06 16:55:47 -070094
95 outputFormat := CharReplacer.Replace(options.Format)
96 if outputFormat == "" {
97 outputFormat = DEFAULT_TRANSFER_FORMAT
98 }
99 if options.Quiet {
100 outputFormat = "{{.Status}}"
101 }
102
103 data := make([]TransferOutput, 1)
Scott Baker72efd752019-05-15 13:12:20 -0700104 data[0].Checksum = upload_result.GetFieldByName("checksum").(string)
105 data[0].Chunks = int(upload_result.GetFieldByName("chunks_received").(int32))
106 data[0].Bytes = int(upload_result.GetFieldByName("bytes_received").(int32))
107 data[0].Status = GetEnumValue(upload_result, "status")
Scott Baker2c0ebda2019-05-06 16:55:47 -0700108
109 result := CommandResult{
110 Format: format.Format(outputFormat),
111 OutputAs: toOutputType(options.OutputAs),
112 Data: data,
113 }
114
115 GenerateOutput(&result)
116
117 return nil
118}
119
120func IsFileUri(s string) bool {
121 return strings.HasPrefix(s, "file://")
122}
123
124func (options *TransferDownload) Execute(args []string) error {
Scott Baker6cf525a2019-05-09 12:25:08 -0700125 conn, descriptor, err := InitReflectionClient()
Scott Baker2c0ebda2019-05-06 16:55:47 -0700126 if err != nil {
127 return err
128 }
129 defer conn.Close()
130
131 local_name := options.Args.LocalFileName
132 uri := options.Args.URI
133
134 if IsFileUri(local_name) {
135 return errors.New("local_name argument should not be a uri")
136 }
137
138 if !IsFileUri(uri) {
139 return errors.New("uri argument should be a file:// uri")
140 }
141
Scott Baker6cf525a2019-05-09 12:25:08 -0700142 h, err := DownloadFile(conn, descriptor, uri, local_name)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700143 if err != nil {
144 return err
145 }
146
147 outputFormat := CharReplacer.Replace(options.Format)
148 if outputFormat == "" {
149 outputFormat = DEFAULT_TRANSFER_FORMAT
150 }
151 if options.Quiet {
152 outputFormat = "{{.Status}}"
153 }
154
155 data := make([]TransferOutput, 1)
156 data[0].Chunks = h.chunks
157 data[0].Bytes = h.bytes
158 data[0].Status = h.status
159
160 result := CommandResult{
161 Format: format.Format(outputFormat),
162 OutputAs: toOutputType(options.OutputAs),
163 Data: data,
164 }
165
166 GenerateOutput(&result)
167
168 return nil
169}