blackstack-nodes 1.2.7 → 1.2.8

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 (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.