factor-connector-ssh 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. data/lib/factor/connector/ssh.rb +169 -0
  2. metadata +126 -0
@@ -0,0 +1,169 @@
1
+ require 'factor-connector-api'
2
+ require 'net/ssh'
3
+ require 'net/scp'
4
+ require 'net/sftp'
5
+ require 'tempfile'
6
+ require 'securerandom'
7
+ require 'uri'
8
+
9
+ Factor::Connector.service 'ssh' do
10
+ action 'execute' do |params|
11
+ host_param = params['host']
12
+ private_key = params['private_key']
13
+ commands = params['commands']
14
+
15
+ fail 'Command is required' unless commands
16
+ fail 'Commands must be an array of strings' unless commands.all? { |c| c.is_a?(String) }
17
+ fail 'Host is required' unless host_param
18
+
19
+ output = ''
20
+ command_lines = []
21
+
22
+ info 'Setting up private key'
23
+ begin
24
+ key_file = Tempfile.new('private')
25
+ key_file.write(private_key)
26
+ key_file.close
27
+ rescue
28
+ fail 'Failed to setup private key'
29
+ end
30
+
31
+ begin
32
+ uri = URI("ssh://#{host_param}")
33
+ host = uri.host
34
+ port = uri.port
35
+ user = uri.user
36
+ rescue => ex
37
+ fail "Couldn't parse input parameters", exception: ex
38
+ end
39
+
40
+ ssh_settings = { keys: [key_file.path] }
41
+ ssh_settings[:port] = port if port
42
+
43
+ fail 'User (user) is required in host address' unless user
44
+ fail 'Host variable must specific host address' unless host
45
+
46
+ begin
47
+ Net::SSH.start(host, user, ssh_settings) do |ssh|
48
+ commands.each do |command|
49
+ info "Executing '#{command}'"
50
+ output_lines = ssh.exec!(command)
51
+ encode_settings = {
52
+ invalid: :replace,
53
+ undef: :replace,
54
+ replace: '?'
55
+ }
56
+ output_lines = output_lines.to_s.encode('UTF-8', encode_settings)
57
+ output << output_lines
58
+ command_lines << {
59
+ lines: output_lines.split("\n"),
60
+ all: output_lines
61
+ }
62
+ end
63
+ end
64
+ rescue Net::SSH::AuthenticationFailed
65
+ fail 'Authentication failure, check your SSH key, username, and host'
66
+ rescue => ex
67
+ fail "Couldn't connect to the server #{user}@#{host}:#{port || '22'}, please check credentials.", exception:ex
68
+ end
69
+
70
+ info 'Cleaning up.'
71
+ begin
72
+ key_file.unlink
73
+ rescue
74
+ warn 'Failed to clean up, but no worries, work will go on.'
75
+ end
76
+ return_info = {
77
+ line: output.split("\n"),
78
+ all: output,
79
+ command: command_lines
80
+ }
81
+ action_callback return_info
82
+ end
83
+
84
+ action 'upload' do |params|
85
+ content = params['content']
86
+ path = params['path']
87
+
88
+ fail 'Content is required' unless content
89
+ fail 'Remote path is required' unless path
90
+
91
+ info 'Setting up private key'
92
+ begin
93
+ output = ''
94
+ key_file = Tempfile.new('private')
95
+ private_key = params['private_key']
96
+ key_file.write(private_key)
97
+ key_file.rewind
98
+ key_file.close
99
+ rescue
100
+ fail 'Private key setup failed'
101
+ end
102
+
103
+ info 'Getting resource'
104
+ begin
105
+ source = Tempfile.new('source')
106
+ source.write open(content).read
107
+ source.rewind
108
+ rescue
109
+ fail 'Getting the resource failed'
110
+ end
111
+
112
+ info 'Parsing input variables'
113
+ begin
114
+ uri = URI("ssh://#{params['host']}")
115
+ host = uri.host
116
+ port = uri.port || params['port']
117
+ user = uri.user || params['username']
118
+
119
+ ssh_settings = { keys: [key_file.path] }
120
+ ssh_settings[:port] = port if port
121
+ rescue
122
+ fail "couldn't parse input parameters"
123
+ end
124
+
125
+ begin
126
+ trail = path[-1] == '/' ? '' : '/'
127
+ remote_directory = "#{path}#{trail}"
128
+ rescue
129
+ fail "The remote path '#{path}' was unparsable"
130
+ end
131
+
132
+ fail "The path #{remote_directory} must be an absolute path" if remote_directory[0] != '/'
133
+
134
+ begin
135
+ Net::SSH.start(host, user, ssh_settings) do |ssh|
136
+ source_path = File.absolute_path(source)
137
+
138
+ Zip::ZipFile.open(source_path) do |zipfile|
139
+ root_path = zipfile.first.name
140
+ zipfile.each do |file|
141
+ next unless file.file?
142
+ remote_zip_path = file.name[root_path.length .. -1]
143
+ destination_path = "#{remote_directory}#{remote_zip_path}"
144
+ info "Uploading #{destination_path}"
145
+ file_contents = file.get_input_stream.read
146
+ string_io = StringIO.new(file_contents)
147
+ zip_dir_path = File.dirname(destination_path)
148
+ begin
149
+ ssh.exec!("mkdir #{zip_dir_path}")
150
+ rescue => ex
151
+ fail "couldn't create the directory #{zip_dir_path}", exception:ex
152
+ end
153
+ begin
154
+ ssh.scp.upload!(string_io, destination_path)
155
+ rescue => ex
156
+ fail "couldn't upload #{destination_path}", exception:ex
157
+ end
158
+ end
159
+ end
160
+ end
161
+ rescue FactorChannelError
162
+ raise
163
+ rescue => ex
164
+ fail "Couldn't connect to the server #{user}@#{host}:#{port || '22'}, please check credentials.", exception:ex
165
+ end
166
+ key_file.unlink
167
+ action_callback
168
+ end
169
+ end
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: factor-connector-ssh
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Maciej Skierkowski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-09-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: net-sftp
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - '='
20
+ - !ruby/object:Gem::Version
21
+ version: 2.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: 2.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.7.0
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.7.0
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.1.2
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.1.2
62
+ - !ruby/object:Gem::Dependency
63
+ name: sshkey
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - '='
68
+ - !ruby/object:Gem::Version
69
+ version: 1.6.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: 1.6.0
78
+ - !ruby/object:Gem::Dependency
79
+ name: factor-connector-api
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.0.1
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.0.1
94
+ description:
95
+ email:
96
+ - maciej@factor.io
97
+ executables: []
98
+ extensions: []
99
+ extra_rdoc_files: []
100
+ files:
101
+ - lib/factor/connector/ssh.rb
102
+ homepage: https://factor.io
103
+ licenses: []
104
+ post_install_message:
105
+ rdoc_options: []
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
120
+ requirements: []
121
+ rubyforge_project:
122
+ rubygems_version: 1.8.25
123
+ signing_key:
124
+ specification_version: 3
125
+ summary: SSH Factor.io Connector
126
+ test_files: []