blackstack-nodes 1.2.3 → 1.2.7

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 +177 -174
  3. metadata +5 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 564b1ff0cb7e036e0e9b934ededf8898c1c2fcec954f510fd9b4081bac502a68
4
- data.tar.gz: 72f9667c3dddd1fd6bee131c3f4420681a6328c4584fe1c3455aa36389e3b87f
3
+ metadata.gz: 37a97d12519b7be33c7f4a15c489043f4925c8a694c1ca5fcaa8766b64dee102
4
+ data.tar.gz: 65616d5b4e683929d19f55fefa8e6a79d383bc7b267beb9ba433bb0685d4c3b0
5
5
  SHA512:
6
- metadata.gz: 6d18846e64fbe0dca169445941d502d45f88d57c7046c0b90a437188a574ae1c619eb04d8ffc0a5ed130d1141112f696fe8a21a7894642b30c066693bc2dbefb
7
- data.tar.gz: 993e4291693c2ed190e924b9186ca2f97c5fef142d70097c3f76741f6d9a85ff9aed77238fed71ffcb3f3483701a4f1e13b056fb1ca7018d240d71c1c617af28
6
+ metadata.gz: 9bb62ee361b49ca1962ab1e793d68767c8f48c5a36d590dcb65809dd14cde861e5cfb042b64634b0479bf53b9ae22bdba619b4c61818caf5d8fc21dd325a920d
7
+ data.tar.gz: b6e79a137d5a38d2af61980f1e76ee6b3a14e800353d759115bfa2801bcfbf5a15a204f28bb8ae119b641a304021334e092ba35fcbcdf26c808167571585a562
@@ -1,175 +1,178 @@
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: does not exist any other element in @@nodes with the same value for the parameter h[:name]
27
- errors << "The parameter h[:name] is not unique" if @@nodes.select{|n| n[:name] == h[:name]}.length > 0
28
-
29
- # validate: the paramerer h has a key :net_remote_ip
30
- errors << "The parameter h does not have a key :net_remote_ip" unless h.has_key?(:net_remote_ip)
31
-
32
- # validate: the paramerer h has a key :ssh_username
33
- errors << "The parameter h does not have a key :ssh_username" unless h.has_key?(:ssh_username)
34
-
35
- # validate: the parameter h[:ssh_username] is a string
36
- errors << "The parameter h[:ssh_username] is not a string" unless h[:ssh_username].is_a?(String)
37
-
38
- # if the parameter h has a key :ssh_private_key_file
39
- if h.has_key?(:ssh_private_key_file)
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
-
43
- # validate: the parameter h[:ssh_private_key_file] is a string
44
- errors << "The parameter h[:ssh_private_key_file] is not a string" unless h[:ssh_private_key_file].is_a?(String)
45
- else
46
- # validate: the parameter h has a key :ssh_password
47
- errors << "The parameter h does not have a key :ssh_password nor :ssh_private_key_file" unless h.has_key?(:ssh_password)
48
-
49
- # validate: the parameter h[:ssh_password] is a string
50
- errors << "The parameter h[:ssh_password] is not a string" unless h[:ssh_password].is_a?(String)
51
- end
52
-
53
- # return
54
- errors
55
- end # def self.descriptor_errors(h)
56
-
57
- def initialize(h, i_logger=nil)
58
- errors = BlackStack::Infrastructure::NodeModule.descriptor_errors(h)
59
- # raise an exception if any error happneed
60
- raise "The node descriptor is not valid: #{errors.uniq.join(".\n")}" if errors.length > 0
61
- # map attributes
62
- self.name = h[:name]
63
- self.net_remote_ip = h[:net_remote_ip]
64
- self.ssh_username = h[:ssh_username]
65
- self.ssh_password = h[:ssh_password]
66
- self.ssh_port = h[:ssh_port]
67
- self.ssh_private_key_file = h[:ssh_private_key_file]
68
-
69
- # create a logger
70
- self.logger = !i_logger.nil? ? i_logger : BlackStack::BaseLogger.new(nil)
71
- end # def self.create(h)
72
-
73
- def to_hash
74
- {
75
- :name => self.name,
76
- :net_remote_ip => self.net_remote_ip,
77
- :ssh_username => self.ssh_username,
78
- :ssh_password => self.ssh_password,
79
- :ssh_port => self.ssh_port,
80
- :ssh_private_key_file => self.ssh_private_key_file,
81
- }
82
- end # def to_hash
83
-
84
- # return true if the node is all set to connect using ssh user and password.
85
- def using_password?
86
- !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_password.nil?
87
- end
88
-
89
- # return true if the node is all set to connect using a private key file.
90
- def using_private_key_file?
91
- !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_private_key_file.nil?
92
- end
93
-
94
- def connect
95
- # connect
96
- if self.using_password?
97
- self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :password => self.ssh_password, :port => self.ssh_port)
98
- elsif self.using_private_key_file?
99
- self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :keys => self.ssh_private_key_file, :port => self.ssh_port)
100
- else
101
- raise "No ssh credentials available"
102
- end
103
- self.ssh
104
- end # def connect
105
-
106
- def disconnect
107
- self.ssh.close
108
- end
109
-
110
- def exec(command)
111
- s = nil
112
- if self.using_password?
113
- s = self.ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c '#{command.gsub("'", "\\'")}'")
114
- elsif self.using_private_key_file?
115
- s = self.ssh.exec!("sudo -S su root -c '#{command.gsub("'", "\\'")}'")
116
- end
117
- s
118
- end # def exec
119
-
120
- def reboot()
121
- tries = 0
122
- max_tries = 20
123
- success = false
124
-
125
- host = self
126
-
127
- logger.logs 'reboot... '
128
- #stdout = host.reboot
129
- begin
130
- stdout = host.ssh.exec!("echo '#{host.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'reboot'")
131
- rescue
132
- end
133
- logger.done #logf("done (#{stdout})")
134
-
135
- while tries < max_tries && !success
136
- begin
137
- tries += 1
138
-
139
- delay = 10
140
- logger.logs "wait #{delay.to_s} seconds... "
141
- sleep(delay)
142
- logger.done
143
-
144
- logger.logs "connecting (try #{tries.to_s})... "
145
- host.connect
146
- logger.done
147
-
148
- success = true
149
- rescue => e
150
- logger.logf e.to_s #error e
151
- end
152
- end # while
153
- raise 'reboot failed' if !success
154
- end # def reboot
155
-
156
- end # module NodeModule
157
-
158
- # TODO: declare these classes (stub and skeleton) using blackstack-rpc
159
- #
160
- # Node Stub
161
- # This class represents a node, without using connection to the database.
162
- # Use this class at the client side.
163
- class Node
164
- include NodeModule
165
- end # class Node
166
- =begin
167
- # Node Skeleton
168
- # This class represents a node, with connection to the database.
169
- # Use this class at the server side.
170
- class Node < Sequel::Model(:node)
171
- include NodeModule
172
- end
173
- =end
174
- end # module Infrastructure
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
175
178
  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.3
4
+ version: 1.2.7
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-05-31 00:00:00.000000000 Z
11
+ date: 2022-06-09 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.