blackstack-nodes 1.2.7 → 1.2.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. checksums.yaml +4 -4
  2. data/lib/blackstack-nodes.rb +188 -177
  3. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 37a97d12519b7be33c7f4a15c489043f4925c8a694c1ca5fcaa8766b64dee102
4
- data.tar.gz: 65616d5b4e683929d19f55fefa8e6a79d383bc7b267beb9ba433bb0685d4c3b0
3
+ metadata.gz: 7dfff9ef5d2e94244befce50fd7dff63ff570be36b54da12e550ef100841c2de
4
+ data.tar.gz: fa9f19672395322af75efafc19d09add8ddc86e510125f4f37433ef7c9c1bd29
5
5
  SHA512:
6
- metadata.gz: 9bb62ee361b49ca1962ab1e793d68767c8f48c5a36d590dcb65809dd14cde861e5cfb042b64634b0479bf53b9ae22bdba619b4c61818caf5d8fc21dd325a920d
7
- data.tar.gz: b6e79a137d5a38d2af61980f1e76ee6b3a14e800353d759115bfa2801bcfbf5a15a204f28bb8ae119b641a304021334e092ba35fcbcdf26c808167571585a562
6
+ metadata.gz: 18abefb039af30eddfca6d081b563b053205e35ee209adb26b1c5e85c3bad8b9ba44198f62552bcc15a76aa5e53d571096881571451d04c4861df60bfbaf1f92
7
+ data.tar.gz: '08df674fc7bcc63bbf792a53d57473bffdd12cc5b72a716ca9b2782e58317e940070b05df16400588d5ab2199827038a0aaa63aa3b3902a15be86abbbfae7257'
@@ -1,178 +1,189 @@
1
- require 'net/ssh'
2
- require 'simple_cloud_logging'
3
- #
4
- module BlackStack
5
- #
6
- module Infrastructure
7
- # this module has attributes an methods used by both classes Node and Node.
8
- module NodeModule
9
- # :name is this is just a descriptive name for the node. It is not the host name, nor the domain, nor any ip.
10
- attr_accessor :name, :net_remote_ip, :ssh_username, :ssh_password, :ssh_port, :ssh_private_key_file
11
- # non-database attributes, used for ssh connection and logging
12
- attr_accessor :ssh, :logger
13
-
14
- def self.descriptor_errors(h)
15
- errors = []
16
-
17
- # validate: the parameter h is a hash
18
- errors << "The parameter h is not a hash" unless h.is_a?(Hash)
19
-
20
- # validate: the parameter h has a key :name
21
- errors << "The parameter h does not have a key :name" unless h.has_key?(:name)
22
-
23
- # validate: the parameter h[:name] is a string
24
- errors << "The parameter h[:name] is not a string" unless h[:name].is_a?(String)
25
-
26
- # validate: the paramerer h has a key :net_remote_ip
27
- errors << "The parameter h does not have a key :net_remote_ip" unless h.has_key?(:net_remote_ip)
28
-
29
- # validate: the paramerer h has a key :ssh_username
30
- errors << "The parameter h does not have a key :ssh_username" unless h.has_key?(:ssh_username)
31
-
32
- # validate: the parameter h[:ssh_username] is a string
33
- errors << "The parameter h[:ssh_username] is not a string" unless h[:ssh_username].is_a?(String)
34
-
35
- # if the parameter h has a key :ssh_private_key_file
36
- if h.has_key?(:ssh_private_key_file) && !h[:ssh_private_key_file].nil?
37
- # validate: the parameter h[:ssh_private_key_file] is a string
38
- errors << "The parameter h[:ssh_private_key_file] is not a string" unless h[:ssh_private_key_file].is_a?(String)
39
-
40
- # validate: the parameter h[:ssh_private_key_file] is a string
41
- errors << "The parameter h[:ssh_private_key_file] is not a string" unless h[:ssh_private_key_file].is_a?(String)
42
- else
43
- # validate: the parameter h has a key :ssh_password
44
- errors << "The parameter h does not have a key :ssh_password nor :ssh_private_key_file" unless h.has_key?(:ssh_password)
45
-
46
- # validate: the parameter h[:ssh_password] is a string
47
- errors << "The parameter h[:ssh_password] is not a string" unless h[:ssh_password].is_a?(String)
48
- end
49
-
50
- # return
51
- errors
52
- end # def self.descriptor_errors(h)
53
-
54
- def initialize(h, i_logger=nil)
55
- errors = BlackStack::Infrastructure::NodeModule.descriptor_errors(h)
56
- # raise an exception if any error happneed
57
- raise "The node descriptor is not valid: #{errors.uniq.join(".\n")}" if errors.length > 0
58
- # map attributes
59
- self.name = h[:name]
60
- self.net_remote_ip = h[:net_remote_ip]
61
- self.ssh_username = h[:ssh_username]
62
- self.ssh_password = h[:ssh_password]
63
- self.ssh_port = h[:ssh_port]
64
- self.ssh_private_key_file = h[:ssh_private_key_file]
65
-
66
- # create a logger
67
- self.logger = !i_logger.nil? ? i_logger : BlackStack::BaseLogger.new(nil)
68
- end # def self.create(h)
69
-
70
- def to_hash
71
- {
72
- :name => self.name,
73
- :net_remote_ip => self.net_remote_ip,
74
- :ssh_username => self.ssh_username,
75
- :ssh_password => self.ssh_password,
76
- :ssh_port => self.ssh_port,
77
- :ssh_private_key_file => self.ssh_private_key_file,
78
- }
79
- end # def to_hash
80
-
81
- # return true if the node is all set to connect using ssh user and password.
82
- def using_password?
83
- !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_password.nil?
84
- end
85
-
86
- # return true if the node is all set to connect using a private key file.
87
- def using_private_key_file?
88
- !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_private_key_file.nil?
89
- end
90
-
91
- def connect
92
- # connect
93
- if self.using_password?
94
- self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :password => self.ssh_password, :port => self.ssh_port)
95
- elsif self.using_private_key_file?
96
- self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :keys => self.ssh_private_key_file, :port => self.ssh_port)
97
- else
98
- raise "No ssh credentials available"
99
- end
100
- self.ssh
101
- end # def connect
102
-
103
- def disconnect
104
- self.ssh.close
105
- end
106
-
107
- def exec(command, sudo=true)
108
- s = nil
109
- command = command.gsub(/'/, "\\\\'")
110
- if sudo
111
- if self.using_password?
112
- s = self.ssh.exec!("echo '#{self.ssh_password.gsub(/'/, "\\\\'")}' | sudo -S su root -c '#{command}'")
113
- elsif self.using_private_key_file?
114
- s = self.ssh.exec!("sudo -S su root -c '#{command}'")
115
- end
116
- else
117
- s = self.ssh.exec!(command)
118
- end
119
- s
120
- end # def exec
121
-
122
- def reboot()
123
- tries = 0
124
- max_tries = 20
125
- success = false
126
-
127
- host = self
128
-
129
- logger.logs 'reboot... '
130
- #stdout = host.reboot
131
- begin
132
- stdout = self.exec("reboot")
133
- rescue
134
- end
135
- logger.done #logf("done (#{stdout})")
136
-
137
- while tries < max_tries && !success
138
- begin
139
- tries += 1
140
-
141
- delay = 10
142
- logger.logs "wait #{delay.to_s} seconds... "
143
- sleep(delay)
144
- logger.done
145
-
146
- logger.logs "connecting (try #{tries.to_s})... "
147
- host.connect
148
- logger.done
149
-
150
- success = true
151
- rescue => e
152
- logger.logf e.to_s #error e
153
- end
154
- end # while
155
- raise 'reboot failed' if !success
156
- end # def reboot
157
-
158
-
159
- end # module NodeModule
160
-
161
- # TODO: declare these classes (stub and skeleton) using blackstack-rpc
162
- #
163
- # Node Stub
164
- # This class represents a node, without using connection to the database.
165
- # Use this class at the client side.
166
- class Node
167
- include NodeModule
168
- end # class Node
169
- =begin
170
- # Node Skeleton
171
- # This class represents a node, with connection to the database.
172
- # Use this class at the server side.
173
- class Node < Sequel::Model(:node)
174
- include NodeModule
175
- end
176
- =end
177
- end # module Infrastructure
1
+ require 'net/ssh'
2
+ require 'shellwords'
3
+ require 'simple_cloud_logging'
4
+ #
5
+ module BlackStack
6
+ #
7
+ module Infrastructure
8
+ # this module has attributes an methods used by both classes Node and Node.
9
+ module NodeModule
10
+ # :name is this is just a descriptive name for the node. It is not the host name, nor the domain, nor any ip.
11
+ attr_accessor :name, :net_remote_ip, :ssh_username, :ssh_password, :ssh_port, :ssh_private_key_file
12
+ # non-database attributes, used for ssh connection and logging
13
+ attr_accessor :ssh, :logger
14
+
15
+ def self.descriptor_errors(h)
16
+ errors = []
17
+
18
+ # validate: the parameter h is a hash
19
+ errors << "The parameter h is not a hash" unless h.is_a?(Hash)
20
+
21
+ # validate: the parameter h has a key :name
22
+ errors << "The parameter h does not have a key :name" unless h.has_key?(:name)
23
+
24
+ # validate: the parameter h[:name] is a string
25
+ errors << "The parameter h[:name] is not a string" unless h[:name].is_a?(String)
26
+
27
+ # validate: the paramerer h has a key :net_remote_ip
28
+ errors << "The parameter h does not have a key :net_remote_ip" unless h.has_key?(:net_remote_ip)
29
+
30
+ # validate: the paramerer h has a key :ssh_username
31
+ errors << "The parameter h does not have a key :ssh_username" unless h.has_key?(:ssh_username)
32
+
33
+ # validate: the parameter h[:ssh_username] is a string
34
+ errors << "The parameter h[:ssh_username] is not a string" unless h[:ssh_username].is_a?(String)
35
+
36
+ # if the parameter h has a key :ssh_private_key_file
37
+ if h.has_key?(:ssh_private_key_file) && !h[:ssh_private_key_file].nil?
38
+ # validate: the parameter h[:ssh_private_key_file] is a string
39
+ errors << "The parameter h[:ssh_private_key_file] is not a string" unless h[:ssh_private_key_file].is_a?(String)
40
+
41
+ # validate: the parameter h[:ssh_private_key_file] is a string
42
+ errors << "The parameter h[:ssh_private_key_file] is not a string" unless h[:ssh_private_key_file].is_a?(String)
43
+ else
44
+ # validate: the parameter h has a key :ssh_password
45
+ errors << "The parameter h does not have a key :ssh_password nor :ssh_private_key_file" unless h.has_key?(:ssh_password)
46
+
47
+ # validate: the parameter h[:ssh_password] is a string
48
+ errors << "The parameter h[:ssh_password] is not a string" unless h[:ssh_password].is_a?(String)
49
+ end
50
+
51
+ # return
52
+ errors
53
+ end # def self.descriptor_errors(h)
54
+
55
+ def initialize(h, i_logger=nil)
56
+ errors = BlackStack::Infrastructure::NodeModule.descriptor_errors(h)
57
+ # raise an exception if any error happneed
58
+ raise "The node descriptor is not valid: #{errors.uniq.join(".\n")}" if errors.length > 0
59
+ # map attributes
60
+ self.name = h[:name]
61
+ self.net_remote_ip = h[:net_remote_ip]
62
+ self.ssh_username = h[:ssh_username]
63
+ self.ssh_password = h[:ssh_password]
64
+ self.ssh_port = h[:ssh_port]
65
+ self.ssh_private_key_file = h[:ssh_private_key_file]
66
+
67
+ # create a logger
68
+ self.logger = !i_logger.nil? ? i_logger : BlackStack::BaseLogger.new(nil)
69
+ end # def self.create(h)
70
+
71
+ def to_hash
72
+ {
73
+ :name => self.name,
74
+ :net_remote_ip => self.net_remote_ip,
75
+ :ssh_username => self.ssh_username,
76
+ :ssh_password => self.ssh_password,
77
+ :ssh_port => self.ssh_port,
78
+ :ssh_private_key_file => self.ssh_private_key_file,
79
+ }
80
+ end # def to_hash
81
+
82
+ # return true if the node is all set to connect using ssh user and password.
83
+ def using_password?
84
+ !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_password.nil?
85
+ end
86
+
87
+ # return true if the node is all set to connect using a private key file.
88
+ def using_private_key_file?
89
+ !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_private_key_file.nil?
90
+ end
91
+
92
+ def connect
93
+ # connect
94
+ if self.using_password?
95
+ self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :password => self.ssh_password, :port => self.ssh_port)
96
+ elsif self.using_private_key_file?
97
+ self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :keys => self.ssh_private_key_file, :port => self.ssh_port)
98
+ else
99
+ raise "No ssh credentials available"
100
+ end
101
+ self.ssh
102
+ end # def connect
103
+
104
+ def disconnect
105
+ self.ssh.close
106
+ end
107
+
108
+ def exec(command, sudo=true)
109
+ code = nil
110
+ if sudo
111
+ if self.using_password?
112
+ code = "echo '#{self.ssh_password}' | sudo -S su root -c '#{command}'"
113
+ elsif self.using_private_key_file?
114
+ code = "sudo -S su root -c '#{command}'"
115
+ end
116
+ else
117
+ code = command
118
+ end
119
+ #puts
120
+ #puts
121
+ #puts code
122
+ #puts
123
+ #puts
124
+ s = self.ssh.exec!(code)
125
+ #puts
126
+ #puts
127
+ #puts s
128
+ #puts
129
+ #puts
130
+ s
131
+ end # def exec
132
+
133
+ def reboot()
134
+ tries = 0
135
+ max_tries = 20
136
+ success = false
137
+
138
+ host = self
139
+
140
+ logger.logs 'reboot... '
141
+ #stdout = host.reboot
142
+ begin
143
+ stdout = self.exec("reboot")
144
+ rescue
145
+ end
146
+ logger.done #logf("done (#{stdout})")
147
+
148
+ while tries < max_tries && !success
149
+ begin
150
+ tries += 1
151
+
152
+ delay = 10
153
+ logger.logs "wait #{delay.to_s} seconds... "
154
+ sleep(delay)
155
+ logger.done
156
+
157
+ logger.logs "connecting (try #{tries.to_s})... "
158
+ host.connect
159
+ logger.done
160
+
161
+ success = true
162
+ rescue => e
163
+ logger.logf e.to_s #error e
164
+ end
165
+ end # while
166
+ raise 'reboot failed' if !success
167
+ end # def reboot
168
+
169
+
170
+ end # module NodeModule
171
+
172
+ # TODO: declare these classes (stub and skeleton) using blackstack-rpc
173
+ #
174
+ # Node Stub
175
+ # This class represents a node, without using connection to the database.
176
+ # Use this class at the client side.
177
+ class Node
178
+ include NodeModule
179
+ end # class Node
180
+ =begin
181
+ # Node Skeleton
182
+ # This class represents a node, with connection to the database.
183
+ # Use this class at the server side.
184
+ class Node < Sequel::Model(:node)
185
+ include NodeModule
186
+ end
187
+ =end
188
+ end # module Infrastructure
178
189
  end # module BlackStack
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blackstack-nodes
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.7
4
+ version: 1.2.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leandro Daniel Sardi
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-06-09 00:00:00.000000000 Z
11
+ date: 2022-06-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-ssh
@@ -66,7 +66,7 @@ homepage: https://github.com/leandrosardi/blackstack-nodes
66
66
  licenses:
67
67
  - MIT
68
68
  metadata: {}
69
- post_install_message:
69
+ post_install_message:
70
70
  rdoc_options: []
71
71
  require_paths:
72
72
  - lib
@@ -82,7 +82,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
82
  version: '0'
83
83
  requirements: []
84
84
  rubygems_version: 3.3.7
85
- signing_key:
85
+ signing_key:
86
86
  specification_version: 4
87
87
  summary: BlackStack Nodes is a simple library to managing a computer remotely via
88
88
  SSH, and perform some common operations.