channelizer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.3
5
+ - jruby-18mode # JRuby in 1.8 mode
6
+ - jruby-19mode # JRuby in 1.9 mode
7
+ - rbx-18mode
8
+ - rbx-19mode
9
+ - ree
data/Gemfile ADDED
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+
3
+ gem 'rake'
4
+
5
+ # Specify your gem's dependencies in channelizer.gemspec
6
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Paul Morton
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1 @@
1
+ Test
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+ require 'rake'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ RSpec::Core::RakeTask.new(:test) do |spec|
9
+ spec.rspec_opts = "-bc"
10
+ end
@@ -0,0 +1,22 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/channelizer/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Paul Morton"]
6
+ gem.email = ["pmorton@biaprotect.com"]
7
+ gem.description = %q{A gem that abstracts shell and upload channels}
8
+ gem.summary = File.read('README.md')
9
+ gem.homepage = ""
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "channelizer"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Channelizer::VERSION
17
+ gem.add_runtime_dependency "winrm", "~> 1.1.2"
18
+ gem.add_runtime_dependency "net-ssh", "~> 2.5.2"
19
+ gem.add_runtime_dependency "net-scp", "~> 1.0.4"
20
+ gem.add_runtime_dependency 'rspec'
21
+ gem.add_runtime_dependency 'rake'
22
+ end
@@ -0,0 +1,7 @@
1
+ require 'winrm'
2
+ require 'channelizer/util/retryable'
3
+ require 'channelizer/exceptions/exceptions'
4
+ require 'channelizer/factory'
5
+ require 'channelizer/channels/base'
6
+ require 'channelizer/channels/winrm'
7
+ require 'channelizer/channels/ssh'
@@ -0,0 +1,130 @@
1
+ module Channelizer
2
+ module Channels
3
+ class Base
4
+ include Channelizer::Exceptions
5
+ include Channelizer::Util::Retryable
6
+
7
+ def initialize(options)
8
+ self.class.validate_options(options)
9
+ end
10
+ # Executes a command on the channel
11
+ #
12
+ # @param [String] command the command to execute on the channel
13
+ # @param [Hash] options the options string to be used in executing the command
14
+ # @option options [Array] :exit_codes ([0]) the valid exit codes for the command
15
+ # @option options [TrueClass,FalseClass] :check_exit_code (true) make that the command returned a valid exit code
16
+ # @return [Fixnum] the exit code of the command
17
+ # @raise [BadExitCode] The command exited with a bad exitcode
18
+ def shell_execute(command, options = {})
19
+ defaults = {:exit_codes => [0], :check_exit_code => true, :sudo => false}
20
+ options = defaults.merge(options)
21
+
22
+ new_command = options[:sudo] ? sudo_command(command) : command
23
+
24
+ exit_code = execute(new_command, options)
25
+
26
+ if not options[:exit_codes].include? exit_code and options[:check_exit_code]
27
+ raise BadExitCode, "Exit Code: #{exit_code}"
28
+ end
29
+
30
+ exit_code.to_i
31
+ end
32
+
33
+ # Returns a command wrapped in a sudo context
34
+ #
35
+ # @param [String] command the command to wrap in a sudo context
36
+ # @return [String] the command that has been wrapped in a sudo context
37
+ # @raise [NotImplementedError] this method has not been implemented
38
+ def sudo_command(command)
39
+ raise NotImplementedError, "sudo command not implemented"
40
+ end
41
+
42
+ # Executes a command on the channel
43
+ #
44
+ # @param command the command to execute on the channel
45
+ # @return [Fixnum]
46
+ # @raise [NotImplementedError] this method has not been implemented
47
+ def execute(command, options = {})
48
+ raise NotImplementedError, "Execute not implemented"
49
+ end
50
+
51
+ # Uploads a file over the channel
52
+ #
53
+ # @param source the file to upload
54
+ # @param destination where to place the file on the remote host
55
+ # @return [Fixnum]
56
+ # @raise [NotImplementedError] this method has not been implemented
57
+ def upload(source, destination, options = {} )
58
+ raise NotImplementedError, "Upload not implemented"
59
+ end
60
+
61
+ # Checks if the channel is ready for action
62
+ #
63
+ # @return [TrueClass,FalseClass]
64
+ def ready?
65
+ begin
66
+ Timeout.timeout(60) do
67
+ execute "hostname"
68
+ end
69
+ return true
70
+ rescue Timeout::Error => e
71
+ return false
72
+ rescue Errno::ECONNREFUSED => e
73
+ return false
74
+ rescue HTTPClient::KeepAliveDisconnected => e
75
+ return false
76
+ end
77
+ end
78
+
79
+ class <<self
80
+ # Validates the option set for the channel
81
+ #
82
+ # @param [Hash] options the options hash to validate
83
+ # @return [True]
84
+ def validate_options(options)
85
+ @required_options.each do |o|
86
+ if o.is_a? Array
87
+ # At least one of the items in an array must be set, if the value is
88
+ # an array it is treated as a group of arguments that are required.
89
+ condition_met = false
90
+ o.each do |o_set|
91
+ if o_set.is_a? Array
92
+ included_options = []
93
+ o_set.each do |o_req_set|
94
+ included_options << o_req_set if options[o_req_set]
95
+ end
96
+ condition_met = true if included_options.length.eql?(o_set.length)
97
+ else
98
+ condition_met = true if options[o_set]
99
+ end
100
+ end
101
+ raise ArgumentError, "You must specify one of #{o.inspect}" unless condition_met
102
+ else
103
+ raise ArgumentError, "#{o} is a required option, but was not provided" unless options[o]
104
+
105
+ if options[o].respond_to? :empty?
106
+ raise ArgumentError, "#{o} cannot be empty" if options[o].empty?
107
+ end
108
+ end
109
+ end
110
+ true
111
+ end
112
+
113
+ # Register a required option
114
+ #
115
+ # @param [Symbol] value the option name that is required
116
+ def required_option(value)
117
+ @required_options ||= []
118
+ if value.respond_to? :to_sym
119
+ @required_options << value.to_sym
120
+ elsif value.is_a? Array
121
+ @required_options << value
122
+ else
123
+ raise ArgumentError, "#{value.inspect} cannot be added to the validation list"
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,107 @@
1
+ require 'net/ssh'
2
+ require 'net/scp'
3
+ module Channelizer
4
+ module Channels
5
+ class Ssh < Channelizer::Channels::Base
6
+
7
+ required_option :host
8
+ required_option :port
9
+ required_option [[:username,:password], :keys]
10
+
11
+ # Creates a SSH Session
12
+ #
13
+ # @option options [String] :username the username
14
+ # @option options [String] :password the password
15
+ # @option options [String] :host the remote host
16
+ # @option options [String] :port (5985) the port to connect on
17
+ # @option options [String] :keys the keys to try logging in with
18
+ def initialize(options)
19
+ defaults = { :port => 22, :paranoid => false }
20
+ options = defaults.merge(options)
21
+
22
+ # Options need to be in a final state before we call the parent initializer
23
+ super(options)
24
+
25
+ @connection_options = options
26
+
27
+ end
28
+
29
+ def session
30
+ options = @connection_options.clone
31
+ host = options.delete(:host)
32
+ username = options.delete(:username)
33
+ Net::SSH.start(host,username,options)
34
+ end
35
+
36
+ # Executes a command on the channel
37
+ #
38
+ # @param command the command to execute on the channel
39
+ # @return [Fixnum] the exit code of the command
40
+ # @raise [StandardException]
41
+ def execute(command, options = { })
42
+ defaults = { :out_console => true }
43
+ options = defaults.merge(options)
44
+ # open a new channel and configure a minimal set of callbacks, then run
45
+ # the event loop until the channel finishes (closes)
46
+ last_exit = -1
47
+ channel = session.open_channel do |ch|
48
+
49
+ #request pty for sudo stuff and so
50
+ ch.request_pty do |ch, success|
51
+ raise "Error requesting pty" unless success
52
+ end
53
+
54
+ ch.exec "#{command}" do |ch, success|
55
+ raise "could not execute command" unless success
56
+
57
+
58
+ # "on_data" is called when the process writes something to stdout
59
+ ch.on_data do |c, data|
60
+ STDOUT.print data if options[:out_console]
61
+
62
+ end
63
+
64
+ # "on_extended_data" is called when the process writes something to stderr
65
+ ch.on_extended_data do |c, type, data|
66
+ STDOUT.print data if options[:out_console]
67
+ end
68
+
69
+ channel.on_request("exit-signal") do |ch, data|
70
+ last_exit = data.read_long
71
+ end
72
+
73
+ channel.on_request("exit-status") do |ch,data|
74
+ last_exit = data.read_long
75
+ end
76
+
77
+ end
78
+ end
79
+ channel.wait
80
+ last_exit
81
+ end
82
+
83
+ # Echos the command (Windows does not support sudo)
84
+ #
85
+ # @param [String] command the command to wrap in a sudo context
86
+ # @return [String] the command that has been wrapped in a sudo context
87
+ def sudo_command(command)
88
+ "sudo #{command}"
89
+ end
90
+
91
+ # Uploads a file over WinRM
92
+ #
93
+ # @param source the file to upload
94
+ # @param destination where to place the file on the remote host
95
+ # @return [Fixnum]
96
+ def upload(source, destination, options = {} )
97
+ options = @connection_options.clone
98
+ host = options.delete(:host)
99
+ username = options.delete(:username)
100
+ channel = session.scp.upload(source,destination)
101
+ channel.wait
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ Channelizer::Factory.register(:ssh, Channelizer::Channels::Ssh)
@@ -0,0 +1,121 @@
1
+ require 'winrm'
2
+ module Channelizer
3
+ module Channels
4
+ class WinRM < Channelizer::Channels::Base
5
+
6
+ # @return [WinRM::WinRMWebService] the winrm management session
7
+ attr_reader :session
8
+
9
+ required_option :host
10
+ required_option :port
11
+ required_option [[:username,:password], :realm]
12
+
13
+ # Creates a WinRM Channel
14
+ #
15
+ # @option options [String] :username the username
16
+ # @option options [String] :password the password
17
+ # @option options [String] :host the remote host
18
+ # @option options [String] :port (5985) the port to connect on
19
+ # @option options [String] :realm the realm to use when using kerberos authentication
20
+ def initialize(options)
21
+ defaults = { :port => 5985, :basic_auth_only => true }
22
+ options = defaults.merge(options)
23
+ options[:pass] = options[:password] if options[:password]
24
+ options[:user] = options[:username] if options[:username]
25
+
26
+ # Options need to be in a final state before we call the parent initializer
27
+ super(options)
28
+
29
+ endpoint = "http://#{options[:host]}:#{options[:port]}/wsman"
30
+
31
+ if options[:realm]
32
+ @session = ::WinRM::WinRMWebService.new(endpoint, :kerberos, :realm => options[:realm])
33
+ else
34
+ @session = ::WinRM::WinRMWebService.new(endpoint, :plaintext, options)
35
+ end
36
+
37
+ end
38
+
39
+ # Executes a command on the channel
40
+ #
41
+ # @param command the command to execute on the channel
42
+ # @return [Fixnum] the exit code of the command
43
+ # @raise [StandardException]
44
+ def execute(command, options = { })
45
+ defaults = { :shell => :cmd, :out_console => true }
46
+ options = defaults.merge(options)
47
+
48
+ run_proc = Proc.new do |stdout, stderr|
49
+ STDOUT.print stdout
50
+ STDERR.print stderr
51
+ end
52
+
53
+ shell = options.delete(:shell)
54
+ case shell
55
+ when :cmd
56
+ if options[:out_console]
57
+ status = session.cmd(command,&run_proc)
58
+ else
59
+ status = session.cmd(command)
60
+ end
61
+ when :powershell
62
+ if options[:out_console]
63
+ status = session.powershell(command, &run_proc)
64
+ else
65
+ status = session.powershell(command)
66
+ end
67
+ else
68
+ raise StandardError, "Invalid shell #{options[:shell]}"
69
+ end
70
+ status[:exitcode]
71
+ end
72
+
73
+ # Echos the command (Windows does not support sudo)
74
+ #
75
+ # @param [String] command the command to wrap in a sudo context
76
+ # @return [String] the command that has been wrapped in a sudo context
77
+ def sudo_command(command)
78
+ command
79
+ end
80
+
81
+ # Uploads a file over WinRM
82
+ #
83
+ # @param source the file to upload
84
+ # @param destination where to place the file on the remote host
85
+ # @return [Fixnum]
86
+ def upload(source, destination, options = {} )
87
+ file = "winrm-upload-#{rand()}"
88
+ puts "File: " + file
89
+ file_name = (session.cmd("echo %TEMP%\\#{file}"))[:data][0][:stdout].chomp
90
+ puts "File Name: " + file_name
91
+ puts session.powershell <<-EOH
92
+ if(Test-Path #{destination})
93
+ {
94
+ rm #{destination}
95
+ }
96
+ EOH
97
+
98
+ Base64.encode64(IO.binread(source)).gsub("\n",'').chars.to_a.each_slice(8000-file_name.size) do |chunk|
99
+ out = session.cmd( "echo #{chunk.join} >> \"#{file_name}\"" )
100
+ puts out
101
+ end
102
+
103
+ puts session.powershell <<-EOH
104
+ $dir = [System.IO.Path]::GetDirectoryName(\"#{destination}\")
105
+ Write-host $dir
106
+ New-Item $dir -type directory -ea SilentlyContinue
107
+ EOH
108
+
109
+ puts session.powershell <<-EOH
110
+ $base64_string = Get-Content \"#{file_name}\"
111
+ $bytes = [System.Convert]::FromBase64String($base64_string)
112
+ $new_file = [System.IO.Path]::GetFullPath(\"#{destination}\")
113
+ [System.IO.File]::WriteAllBytes($new_file,$bytes)
114
+ EOH
115
+ end
116
+
117
+ end
118
+ end
119
+ end
120
+
121
+ Channelizer::Factory.register(:winrm, Channelizer::Channels::WinRM)
@@ -0,0 +1,13 @@
1
+ module Channelizer
2
+ module Exceptions
3
+ # Generic Channel Error
4
+ class ChannelError < StandardError ; end
5
+
6
+ # Invalid Exit Code
7
+ class BadExitCode < StandardError ; end
8
+
9
+ # Invalid Channel Type Code
10
+ class InvalidChannelTypeError < StandardError ; end
11
+
12
+ end
13
+ end
@@ -0,0 +1,23 @@
1
+ module Channelizer
2
+ class Factory
3
+ include Channelizer::Exceptions
4
+
5
+ class << self
6
+
7
+ def register(name,klass)
8
+ @registered_channels ||= {}
9
+ @registered_channels[name.to_sym] = klass
10
+ end
11
+
12
+ def build_channel(type,options)
13
+ raise InvalidChannelTypeError, ":#{type} is not a registered channel" unless @registered_channels[type.to_sym]
14
+ @registered_channels[type.to_sym].new(options)
15
+ end
16
+
17
+ def channels
18
+ @registered_channels ||= {}
19
+ end
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Channelizer
2
+ module Util
3
+ module Retryable
4
+ # Retries a given block a specified number of times in the
5
+ # event the specified exception is raised. If the retries
6
+ # run out, the final exception is raised.
7
+ #
8
+ # This code is adapted slightly from the following blog post:
9
+ # http://blog.codefront.net/2008/01/14/retrying-code-blocks-in-ruby-on-exceptions-whatever/
10
+ def retryable(opts=nil)
11
+ opts = { :tries => 1, :on => Exception }.merge(opts || {})
12
+
13
+ begin
14
+ return yield
15
+ rescue *opts[:on]
16
+ if (opts[:tries] -= 1) > 0
17
+ sleep opts[:sleep].to_f if opts[:sleep]
18
+ retry
19
+ end
20
+ raise
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,3 @@
1
+ module Channelizer
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,19 @@
1
+ $: << File.dirname(__FILE__) + '../lib/'
2
+ $: << File.dirname(__FILE__)
3
+ require 'channelizer'
4
+ module ChannelHelper
5
+
6
+ def new_channel(type)
7
+ case type
8
+ when :winrm
9
+ Channelizer::Factory.build_channel(type, :username => 'vagrant', :password => 'vagrant', :host => 'localhost', :port => 5985)
10
+ when :ssh
11
+ Channelizer::Factory.build_channel(type, :username => 'vagrant', :keys => ['/Users/pmorton/.ssh/deploy'],:password => 'vagrant', :host => 'localhost', :port => 2200)
12
+ end
13
+ end
14
+
15
+ end
16
+
17
+ RSpec.configure do |config|
18
+ config.include(ChannelHelper)
19
+ end
@@ -0,0 +1 @@
1
+ This is a test upload
@@ -0,0 +1,16 @@
1
+ require 'channel_helper.rb'
2
+ describe "winrm object form" do
3
+ it 'should expose a session' do
4
+ c = Channelizer::Factory.build_channel(:winrm, :host => 'localhost', :username => 'vagrant', :password => 'vagrant')
5
+ c.session.should be_a_kind_of(WinRM::WinRMWebService)
6
+ end
7
+
8
+ it 'should respond to instance methods of the base interface' do
9
+ c = Channelizer::Factory.build_channel(:winrm, :host => 'localhost', :username => 'vagrant', :password => 'vagrant')
10
+ c.should respond_to(:execute,:upload,:shell_execute,:sudo_command, :ready?)
11
+ end
12
+
13
+ it 'should respond to class methods of the base interface' do
14
+ Channelizer::Channels::WinRM.should respond_to(:validate_options)
15
+ end
16
+ end
@@ -0,0 +1,111 @@
1
+ require 'channel_helper.rb'
2
+
3
+ Channelizer::Factory.channels.each do |channel,klass|
4
+ puts "CLASS #{channel}"
5
+ describe "#{channel} command execution" do
6
+ before(:all) do
7
+ @channel = new_channel(channel.to_sym)
8
+ puts @channel
9
+ end
10
+
11
+ it 'should echo back a sudo command' do
12
+ @channel.sudo_command('test_command').should == "sudo test_command" unless channel.to_sym.eql? :winrm
13
+ end
14
+
15
+ it 'should execute a command sucessfully' do
16
+ @channel.execute('hostname').should == 0
17
+ end
18
+ end
19
+
20
+ describe "#{channel} shell execution" do
21
+ before(:all) do
22
+ @channel = new_channel(:winrm)
23
+ end
24
+
25
+ it 'should except when non-zero exit code is specified' do
26
+ expect {
27
+ @channel.shell_execute('exit 1')
28
+ }.to raise_error(Channelizer::Exceptions::BadExitCode, /1/)
29
+ end
30
+
31
+ it 'should NOT except when non-zero exit code is specified and it has been told not to' do
32
+ @channel.shell_execute('exit 1',:check_exit_code => false)
33
+ end
34
+
35
+ it 'should except based on custom error codes' do
36
+ expect {
37
+ @channel.shell_execute('exit 0', :exit_codes => [1,2])
38
+ }.to raise_error(Channelizer::Exceptions::BadExitCode, /0/)
39
+ end
40
+
41
+ it 'should return the exit code of the command' do
42
+ @channel.shell_execute('exit 1',:check_exit_code => false).should == 1
43
+ end
44
+
45
+ it 'should output stuff to the console' do
46
+ STDOUT.should_receive(:print).with("test message\r\n")
47
+ @channel.shell_execute('echo test message')
48
+ end
49
+
50
+ it 'should NOT output stuff to the console' do
51
+ STDOUT.should_not_receive(:print).with("test message\r\n")
52
+ @channel.shell_execute('echo test message', :out_console => false)
53
+ end
54
+ end
55
+
56
+ describe "#{channel} upload" do
57
+ before(:all) do
58
+ @channel = new_channel(channel.to_sym)
59
+ end
60
+
61
+
62
+ end
63
+
64
+ describe "#{channel} interogatory methods" do
65
+ before(:all) do
66
+ @channel = new_channel(channel.to_sym)
67
+ end
68
+
69
+ it 'should be ready' do
70
+ @channel.ready?.should == true
71
+ end
72
+ end
73
+ end
74
+
75
+ describe 'winrm specifc functionality' do
76
+ before(:all) do
77
+ @channel = new_channel(:winrm)
78
+ end
79
+
80
+ it 'should echo back a sudo command' do
81
+ @channel.sudo_command('test_command').should == "test_command"
82
+ end
83
+
84
+ it 'should execute in powershell when requested' do
85
+ @channel.execute('dir ENV:\\', :shell => :powershell).should == 0
86
+ @channel.execute('dir ENV:\\').should == 1
87
+ end
88
+
89
+ it 'should upload a file' do
90
+ @channel.upload('./spec/test_data/test_file.txt', 'C:\test_file.txt')
91
+ STDOUT.should_receive(:print).with("This is a test upload")
92
+ (@channel.execute "type test_file.txt") == 0
93
+
94
+ end
95
+
96
+ end
97
+
98
+ describe 'ssh specifc functionality' do
99
+ before(:all) do
100
+ @channel = new_channel(:ssh)
101
+ end
102
+
103
+ it 'should upload a file' do
104
+ @channel.upload('./spec/test_data/test_file.txt', '/tmp/test_file.txt')
105
+ STDOUT.should_receive(:print).with("This is a test upload")
106
+ (@channel.execute "cat /tmp/test_file.txt") == 0
107
+
108
+ end
109
+
110
+ end
111
+
@@ -0,0 +1,38 @@
1
+ require 'channel_helper.rb'
2
+
3
+ describe "winrm option parsing" do
4
+ it 'should require a host' do
5
+ expect {
6
+ Channelizer::Factory.build_channel(:winrm, :username => 'vagrant', :password => 'vagrant', :port => 5985)
7
+ }.to raise_error(ArgumentError, /host is a required option/)
8
+ end
9
+
10
+ it 'should use the default port' do
11
+ Channelizer::Factory.build_channel(:winrm, :host => 'localhost', :username => 'vagrant', :password => 'vagrant')
12
+ end
13
+
14
+ # Requires a wokring kerberos setup
15
+ #it 'should not require username and password if kerberos is specified' do
16
+ # Channelizer::Factory.build_channel(:winrm, :host => 'localhost', :realm => 'test')
17
+ #end
18
+
19
+ it 'should require a username and password' do
20
+ expect {
21
+ Channelizer::Factory.build_channel(:winrm, :host => 'localhost')
22
+ }.to raise_error(ArgumentError, /You must specify one of \[\[\:username, \:password\]/)
23
+ end
24
+
25
+ it 'should require a username even if a password is given' do
26
+ expect {
27
+ Channelizer::Factory.build_channel(:winrm, :host => 'localhost', :password => 'vagrant')
28
+ }.to raise_error(ArgumentError, /You must specify one of \[\[\:username, \:password\]/)
29
+ end
30
+
31
+ it 'should require a password even if a username is given' do
32
+ expect {
33
+ Channelizer::Factory.build_channel(:winrm, :host => 'localhost', :username => 'vagrant')
34
+ }.to raise_error(ArgumentError, /You must specify one of \[\[\:username, \:password\]/)
35
+ end
36
+
37
+ end
38
+
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: channelizer
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Paul Morton
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: winrm
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.1.2
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.1.2
30
+ - !ruby/object:Gem::Dependency
31
+ name: net-ssh
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 2.5.2
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 2.5.2
46
+ - !ruby/object:Gem::Dependency
47
+ name: net-scp
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.0.4
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.0.4
62
+ - !ruby/object:Gem::Dependency
63
+ name: rspec
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rake
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ description: A gem that abstracts shell and upload channels
95
+ email:
96
+ - pmorton@biaprotect.com
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - .gitignore
102
+ - .travis.yml
103
+ - Gemfile
104
+ - LICENSE
105
+ - README.md
106
+ - Rakefile
107
+ - channelizer.gemspec
108
+ - lib/channelizer.rb
109
+ - lib/channelizer/channels/base.rb
110
+ - lib/channelizer/channels/ssh.rb
111
+ - lib/channelizer/channels/winrm.rb
112
+ - lib/channelizer/exceptions/exceptions.rb
113
+ - lib/channelizer/factory.rb
114
+ - lib/channelizer/util/retryable.rb
115
+ - lib/channelizer/version.rb
116
+ - spec/channel_helper.rb
117
+ - spec/test_data/test_file.txt
118
+ - spec/winrm_form_spec.rb
119
+ - spec/winrm_functional_spec.rb
120
+ - spec/winrm_options_spec.rb
121
+ homepage: ''
122
+ licenses: []
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ none: false
129
+ requirements:
130
+ - - ! '>='
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ segments:
134
+ - 0
135
+ hash: -721956935773256320
136
+ required_rubygems_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
143
+ - 0
144
+ hash: -721956935773256320
145
+ requirements: []
146
+ rubyforge_project:
147
+ rubygems_version: 1.8.24
148
+ signing_key:
149
+ specification_version: 3
150
+ summary: Test
151
+ test_files:
152
+ - spec/channel_helper.rb
153
+ - spec/test_data/test_file.txt
154
+ - spec/winrm_form_spec.rb
155
+ - spec/winrm_functional_spec.rb
156
+ - spec/winrm_options_spec.rb