File Coverage

blib/lib/XAS/Lib/WS/Transfer.pm
Criterion Covered Total %
statement 3 113 2.6
branch 0 6 0.0
condition n/a
subroutine 1 15 6.6
pod 7 7 100.0
total 11 141 7.8


line stmt bran cond sub pod time code
1             package XAS::Lib::WS::Transfer;
2              
3             our $VERSION = '0.01';
4              
5             use XAS::Class
6 1         5 version => $VERSION,
7             base => 'XAS::Lib::WS::RemoteShell',
8             codecs => 'base64 unicode',
9             utils => ':validation dotid',
10             constant => 'SCALAR',
11 1     1   1239 ;
  1         2  
12              
13             # ----------------------------------------------------------------------
14             # Public Methods
15             # ----------------------------------------------------------------------
16              
17             sub get {
18 0     0 1   my $self = shift;
19 0           my $p = validate_params(\@_, {
20             -local => { type => SCALAR },
21             -remote => { type => SCALAR },
22             });
23              
24 0           my $local = $p->{'local'};
25 0           my $remote = $p->{'remote'};
26              
27             # this assumes that the remote WS-Manage server is Microsoft based
28             # otherwise you would use something sensible like scp
29              
30 0           my $fh;
31 0           my $code = $self->_code_get_powershell($remote);
32 0           my $invoke = "powershell -noprofile -encodedcommand $code";
33              
34 0           $self->command($invoke);
35 0           $self->receive();
36 0           $self->check_exitcode();
37            
38 0 0         if (open($fh, '>', $local)) {
39              
40 0           print $fh decode_base64($self->stdout);
41 0           close $fh;
42              
43             } else {
44              
45 0           $self->throw_msg(
46             dotid($self->class) . '.put.badfile',
47             'file_create',
48             $local, $!
49             );
50              
51             }
52              
53 0           return $self->exitcode;
54              
55             }
56              
57             sub put {
58 0     0 1   my $self = shift;
59 0           my $p = validate_params(\@_, {
60             -local => { type => SCALAR },
61             -remote => { type => SCALAR },
62             });
63              
64 0           my $local = $p->{'local'};
65 0           my $remote = $p->{'remote'};
66              
67             # this assumes that the remote WS-Manage server is Microsoft based
68             # otherwise you would use something sensible like scp
69              
70 0           my $fh;
71 0           my $size = 30 * 57;
72 0           my $invoke = 'powershell -noprofile -encodedcommand %s';
73              
74 0 0         if (open($fh, '<', $local)) {
75              
76 0           while (read($fh, my $buf, $size)) {
77              
78 0           my $data = encode_base64($buf, '');
79 0           my $code = $self->_code_put_powershell($remote, $data);
80 0           my $cmd = sprintf($invoke, $code);
81              
82 0           $self->command($cmd);
83 0           $self->receive();
84 0           $self->check_exitcode();
85              
86             }
87              
88 0           close $fh;
89              
90             } else {
91              
92 0           $self->throw_msg(
93             dotid($self->class) . '.put.badfile',
94             'file_create',
95             $local, $!
96             );
97              
98             }
99              
100 0           return $self->exitcode;
101              
102             }
103              
104             sub exists {
105 0     0 1   my $self = shift;
106 0           my ($path) = validate_params(\@_, [1]);
107              
108 0           my $code = $self->_code_exists_powershell($path);
109 0           my $invoke = "powershell -noprofile -encodedcommand $code";
110              
111 0           $self->command($invoke);
112 0           $self->receive();
113 0           $self->check_exitcode();
114              
115 0 0         return $self->exitcode ? 0 : 1;
116              
117             }
118              
119             sub mkdir {
120 0     0 1   my $self = shift;
121 0           my ($path) = validate_params(\@_, [1]);
122              
123 0           my $code = $self->_code_mkdir_powershell($path);
124 0           my $invoke = "powershell -noprofile -encodedcommand $code";
125              
126 0           $self->command($invoke);
127 0           $self->receive();
128 0           $self->check_exitcode();
129              
130 0           return $self->exitcode;
131              
132             }
133              
134             sub rmdir {
135 0     0 1   my $self = shift;
136 0           my ($path) = validate_params(\@_, [1]);
137              
138 0           my $code = $self->_code_rmdir_powershell($path);
139 0           my $invoke = "powershell -noprofile -encodedcommand $code";
140              
141 0           $self->command($invoke);
142 0           $self->receive();
143 0           $self->check_exitcode();
144              
145 0           return $self->exitcode;
146              
147             }
148              
149             sub del {
150 0     0 1   my $self = shift;
151 0           my ($path) = validate_params(\@_, [1]);
152              
153 0           my $code = $self->_code_del_powershell($path);
154 0           my $invoke = "powershell -noprofile -encodedcommand $code";
155              
156 0           $self->command($invoke);
157 0           $self->receive();
158 0           $self->check_exitcode();
159              
160 0           return $self->exitcode;
161              
162             }
163              
164             sub dir {
165 0     0 1   my $self = shift;
166 0           my ($path) = validate_params(\@_, [1]);
167              
168 0           my $code = $self->_code_dir_powershell($path);
169 0           my $invoke = "powershell -noprofile -encodedcommand $code";
170              
171 0           $self->command($invoke);
172 0           $self->receive();
173 0           $self->check_exitcode();
174              
175 0           return $self->stdout;
176              
177             }
178              
179             # ----------------------------------------------------------------------
180             # Private Methods
181             # ----------------------------------------------------------------------
182              
183             # ----------------------------------------------------------------------
184             # Powershell Boilerplate - yeah heredoc...
185             #
186             # some powershell code borrowed from
187             # https://github.com/WinRb/winrm-fs/tree/master/lib/winrm-fs/scripts
188             # ----------------------------------------------------------------------
189              
190             sub _code_put_powershell {
191 0     0     my $self = shift;
192 0           my $filename = shift;
193 0           my $data = shift;
194              
195 0           my $code = <<'CODE';
196             $ProgressPreference='SilentlyContinue'
197             try {
198             $data = '__DATA__'
199             $bytes = [System.Convert]::FromBase64String($data)
200             $file = [System.IO.File]::Open('__FILENAME__', 'Append')
201             $file.Write($bytes, 0, $bytes.Length)
202             $file.Close()
203             exit 0
204             } catch {
205             Write-Error -Message $_.Exception.Message
206             exit 1
207             }
208             CODE
209              
210 0           $code =~ s/__FILENAME__/$filename/;
211 0           $code =~ s/__DATA__/$data/;
212              
213 0           return encode_base64(encode_unicode('UTF-16LE', $code), '');
214              
215             }
216              
217             sub _code_get_powershell {
218 0     0     my $self = shift;
219 0           my $filename = shift;
220              
221 0           my $code = <<'CODE';
222             $ProgressPreference='SilentlyContinue'
223             $p = $ExecutionContext.SessionState.Path
224             $path = $p.GetUnresolvedProviderPathFromPSPath('__FILENAME__')
225             if (Test-Path $path -PathType Leaf) {
226             $bytes = [System.convert]::ToBase64String([System.IO.File]::ReadAllBytes($path))
227             Write-Host $bytes
228             exit 0
229             }
230             Write-Error -Message 'File not found'
231             exit 1
232             CODE
233              
234 0           $code =~ s/__FILENAME__/$filename/;
235              
236 0           return encode_base64(encode_unicode('UTF-16LE', $code), '');
237              
238             }
239              
240             sub _code_exists_powershell {
241 0     0     my $self = shift;
242 0           my $path = shift;
243              
244 0           my $code = <<'CODE';
245             $ProgressPreference='SilentlyContinue'
246             $p = $ExecutionContext.SessionState.Path
247             $path = $p.GetUnresolvedProviderPathFromPSPath('__PATH__')
248             if (Test-Path $path) {
249             exit 0
250             } else {
251             Write-Error -Message '__PATH__ not found'
252             exit 1
253             }
254             CODE
255              
256 0           $code =~ s/__PATH__/$path/g;
257              
258 0           return encode_base64(encode_unicode('UTF-16LE', $code), '');
259              
260             }
261              
262             sub _code_mkdir_powershell {
263 0     0     my $self = shift;
264 0           my $path = shift;
265              
266 0           my $code = <<'CODE';
267             $ProgressPreference='SilentlyContinue'
268             $p = $ExecutionContext.SessionState.Path
269             $path = $p.GetUnresolvedProviderPathFromPSPath('__PATH__')
270             if (!(Test-Path $path)) {
271             New-Item -ItemType Directory -Force -Path $path | Out-Null
272             exit 0
273             }
274             Write-Error -Message '__PATH__ not found'
275             exit 1
276             CODE
277              
278 0           $code =~ s/__PATH__/$path/g;
279              
280 0           return encode_base64(encode_unicode('UTF-16LE', $code), '');
281              
282             }
283              
284             sub _code_rmdir_powershell {
285 0     0     my $self = shift;
286 0           my $path = shift;
287              
288 0           my $code = <<'CODE';
289             $ProgressPreference='SilentlyContinue'
290             $p = $ExecutionContext.SessionState.Path
291             $path = $p.GetUnresolvedProviderPathFromPSPath('__PATH__')
292             if (Test-Path $path) {
293             Remove-Item $path -Force
294             exit 0
295             }
296             Write-Error -Message '__PATH__ not found'
297             exit 1
298             CODE
299              
300 0           $code =~ s/__PATH__/$path/g;
301              
302 0           return encode_base64(encode_unicode('UTF-16LE', $code), '');
303              
304             }
305              
306             sub _code_del_powershell {
307 0     0     my $self = shift;
308 0           my $path = shift;
309              
310 0           my $code = <<'CODE';
311             $ProgressPreference='SilentlyContinue'
312             $p = $ExecutionContext.SessionState.Path
313             $path = $p.GetUnresolvedProviderPathFromPSPath('__PATH__')
314             if (Test-Path $path) {
315             Remove-Item $path -Force
316             exit 0
317             }
318             Write-Error -Message '__PATH__ not found'
319             exit 1
320             CODE
321              
322 0           $code =~ s/__PATH__/$path/g;
323              
324 0           return encode_base64(encode_unicode('UTF-16LE', $code), '');
325              
326             }
327              
328             sub _code_dir_powershell {
329 0     0     my $self = shift;
330 0           my $path = shift;
331              
332 0           my $code = <<'CODE';
333             $ProgressPreference='SilentlyContinue'
334             $p = $ExecutionContext.SessionState.Path
335             $path = $p.GetUnresolvedProviderPathFromPSPath('__PATH__')
336             if (Test-Path $path) {
337             Get-ChildItem -Path __PATH__
338             exit 0
339             }
340             Write-Error -Message '__PATH__ not found'
341             exit 1
342             CODE
343              
344 0           $code =~ s/__PATH__/$path/g;
345              
346 0           return encode_base64(encode_unicode('UTF-16LE', $code), '');
347              
348             }
349              
350             1;
351              
352             __END__