blob: e7460583603b5623192638ef48f11d1caa61ef52 [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 flags "github.com/jessevdk/go-flags"
Scott Baker20481aa2019-06-20 11:00:54 -070021 corderrors "github.com/opencord/cordctl/error"
Scott Baker2c0ebda2019-05-06 16:55:47 -070022 "strings"
23)
24
25const (
26 DEFAULT_TRANSFER_FORMAT = "table{{ .Status }}\t{{ .Checksum }}\t{{ .Chunks }}\t{{ .Bytes }}"
27)
28
29type TransferOutput struct {
30 Status string `json:"status"`
31 Checksum string `json:"checksum"`
32 Chunks int `json:"chunks"`
33 Bytes int `json:"bytes"`
34}
35
36type TransferUpload struct {
37 OutputOptions
38 ChunkSize int `short:"h" long:"chunksize" default:"65536" description:"Host and port"`
39 Args struct {
40 LocalFileName string
41 URI string
42 } `positional-args:"yes" required:"yes"`
43}
44
45type TransferDownload struct {
46 OutputOptions
47 Args struct {
48 URI string
49 LocalFileName string
50 } `positional-args:"yes" required:"yes"`
51}
52
53type TransferOpts struct {
54 Upload TransferUpload `command:"upload"`
55 Download TransferDownload `command:"download"`
56}
57
58var transferOpts = TransferOpts{}
59
60func RegisterTransferCommands(parser *flags.Parser) {
61 parser.AddCommand("transfer", "file transfer commands", "Commands to transfer files to and from XOS", &transferOpts)
62}
63
Scott Baker2c0ebda2019-05-06 16:55:47 -070064/* Command processors */
65
66func (options *TransferUpload) Execute(args []string) error {
67
Scott Baker867aa302019-06-19 13:18:45 -070068 conn, descriptor, err := InitClient(INIT_DEFAULT)
Scott Baker2c0ebda2019-05-06 16:55:47 -070069 if err != nil {
70 return err
71 }
72 defer conn.Close()
73
74 local_name := options.Args.LocalFileName
75 uri := options.Args.URI
76
Scott Baker6cf525a2019-05-09 12:25:08 -070077 if IsFileUri(local_name) {
Scott Baker20481aa2019-06-20 11:00:54 -070078 return corderrors.NewInvalidInputError("local_name argument should not be a uri")
Scott Baker2c0ebda2019-05-06 16:55:47 -070079 }
80
Scott Baker6cf525a2019-05-09 12:25:08 -070081 if !IsFileUri(uri) {
Scott Baker20481aa2019-06-20 11:00:54 -070082 return corderrors.NewInvalidInputError("uri argument should be a file:// uri")
Scott Baker2c0ebda2019-05-06 16:55:47 -070083 }
84
Scott Baker72efd752019-05-15 13:12:20 -070085 h, upload_result, err := UploadFile(conn, descriptor, local_name, uri, options.ChunkSize)
Scott Baker55694ca2019-06-13 14:52:28 -070086 if err != nil {
87 return err
88 }
Scott Baker72efd752019-05-15 13:12:20 -070089
90 if upload_result.GetFieldByName("checksum").(string) != h.GetChecksum() {
Scott Baker20481aa2019-06-20 11:00:54 -070091 return corderrors.WithStackTrace(&corderrors.ChecksumMismatchError{
92 Expected: h.GetChecksum(),
93 Actual: upload_result.GetFieldByName("checksum").(string)})
Scott Baker72efd752019-05-15 13:12:20 -070094 }
Scott Baker2c0ebda2019-05-06 16:55:47 -070095
Scott Baker2c0ebda2019-05-06 16:55:47 -070096 data := make([]TransferOutput, 1)
Scott Baker72efd752019-05-15 13:12:20 -070097 data[0].Checksum = upload_result.GetFieldByName("checksum").(string)
98 data[0].Chunks = int(upload_result.GetFieldByName("chunks_received").(int32))
99 data[0].Bytes = int(upload_result.GetFieldByName("bytes_received").(int32))
100 data[0].Status = GetEnumValue(upload_result, "status")
Scott Baker2c0ebda2019-05-06 16:55:47 -0700101
Scott Baker5281d002019-05-16 10:45:26 -0700102 FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_TRANSFER_FORMAT, "{{.Status}}", data)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700103
104 return nil
105}
106
107func IsFileUri(s string) bool {
108 return strings.HasPrefix(s, "file://")
109}
110
111func (options *TransferDownload) Execute(args []string) error {
Scott Baker867aa302019-06-19 13:18:45 -0700112 conn, descriptor, err := InitClient(INIT_DEFAULT)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700113 if err != nil {
114 return err
115 }
116 defer conn.Close()
117
118 local_name := options.Args.LocalFileName
119 uri := options.Args.URI
120
121 if IsFileUri(local_name) {
Scott Baker20481aa2019-06-20 11:00:54 -0700122 return corderrors.NewInvalidInputError("local_name argument should not be a uri")
Scott Baker2c0ebda2019-05-06 16:55:47 -0700123 }
124
125 if !IsFileUri(uri) {
Scott Baker20481aa2019-06-20 11:00:54 -0700126 return corderrors.NewInvalidInputError("uri argument should be a file:// uri")
Scott Baker2c0ebda2019-05-06 16:55:47 -0700127 }
128
Scott Baker6cf525a2019-05-09 12:25:08 -0700129 h, err := DownloadFile(conn, descriptor, uri, local_name)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700130 if err != nil {
131 return err
132 }
133
Scott Baker2c0ebda2019-05-06 16:55:47 -0700134 data := make([]TransferOutput, 1)
135 data[0].Chunks = h.chunks
136 data[0].Bytes = h.bytes
137 data[0].Status = h.status
Scott Baker5281d002019-05-16 10:45:26 -0700138 data[0].Checksum = h.GetChecksum()
Scott Baker2c0ebda2019-05-06 16:55:47 -0700139
Scott Baker5281d002019-05-16 10:45:26 -0700140 FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_TRANSFER_FORMAT, "{{.Status}}", data)
Scott Baker2c0ebda2019-05-06 16:55:47 -0700141
142 return nil
143}