factor-connector-ssh 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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: []