blackstack-nodes 1.2.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 (3) hide show
  1. checksums.yaml +7 -0
  2. data/lib/blackstack-nodes.rb +165 -0
  3. metadata +89 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: fb7a3667e0fc16e9c60520b064a64a12e80dea2959f19124873f95294e2ed1ec
4
+ data.tar.gz: 587ad2802afae306d0c8d92a70927f2c7385d0540442c5bb6de89ec275a3436a
5
+ SHA512:
6
+ metadata.gz: b4ac396a8caf6f4ec5173863d8613ecebd8ce5f3c82421ea17ffca122da779aadd05fcf91391de3d26e672aa643c7fd5b33364daa0eeca4f2a5b1973223b9910
7
+ data.tar.gz: 418f53712263a75c07bcbd3d4bfa9717b90ba7a6904090acd16caf9f1c9fbdf60aed8a429ee7baff02f2fe71adbb9a746281eee779a87ee2cab915123f9f3ca1
@@ -0,0 +1,165 @@
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
+ attr_accessor :ssh, :logger
10
+
11
+ def self.descriptor_errors(h)
12
+ errors = []
13
+
14
+ # validate: the parameter h is a hash
15
+ errors << "The parameter h is not a hash" unless h.is_a?(Hash)
16
+
17
+ # validate: the paramerer h has a key :net_remote_ip
18
+ errors << "The parameter h does not have a key :net_remote_ip" unless h.has_key?(:net_remote_ip)
19
+
20
+ # validate: the paramerer h has a key :ssh_username
21
+ errors << "The parameter h does not have a key :ssh_username" unless h.has_key?(:ssh_username)
22
+
23
+ # validate: the parameter h[:ssh_username] is a string
24
+ errors << "The parameter h[:ssh_username] is not a string" unless h[:ssh_username].is_a?(String)
25
+
26
+ # if the parameter h has a key :ssh_private_key_file
27
+ if h.has_key?(:ssh_private_key_file)
28
+ # validate: the parameter h[:ssh_private_key_file] is a string
29
+ errors << "The parameter h[:ssh_private_key_file] is not a string" unless h[:ssh_private_key_file].is_a?(String)
30
+
31
+ # validate: the parameter h[:ssh_private_key_file] is a string
32
+ errors << "The parameter h[:ssh_private_key_file] is not a string" unless h[:ssh_private_key_file].is_a?(String)
33
+ else
34
+ # validate: the parameter h has a key :ssh_password
35
+ errors << "The parameter h does not have a key :ssh_password nor :ssh_private_key_file" unless h.has_key?(:ssh_password)
36
+
37
+ # validate: the parameter h[:ssh_password] is a string
38
+ errors << "The parameter h[:ssh_password] is not a string" unless h[:ssh_password].is_a?(String)
39
+ end
40
+
41
+ # return
42
+ errors
43
+ end # def self.descriptor_errors(h)
44
+
45
+ def initialize(h, i_logger=nil)
46
+ errors = BlackStack::Infrastructure::NodeModule.descriptor_errors(h)
47
+ # raise an exception if any error happneed
48
+ raise "The node descriptor is not valid: #{errors.uniq.join(".\n")}" if errors.length > 0
49
+ # map attributes
50
+ self.name = h[:name]
51
+ self.net_remote_ip = h[:net_remote_ip]
52
+ self.ssh_username = h[:ssh_username]
53
+ self.ssh_password = h[:ssh_password]
54
+ self.ssh_port = h[:ssh_port]
55
+ self.ssh_private_key_file = h[:ssh_private_key_file]
56
+
57
+ # create a logger
58
+ self.logger = !i_logger.nil? ? i_logger : BlackStack::BaseLogger.new(nil)
59
+ end # def self.create(h)
60
+
61
+ def to_hash
62
+ {
63
+ :name => self.name,
64
+ :net_remote_ip => self.net_remote_ip,
65
+ :ssh_username => self.ssh_username,
66
+ :ssh_password => self.ssh_password,
67
+ :ssh_port => self.ssh_port,
68
+ :ssh_private_key_file => self.ssh_private_key_file,
69
+ }
70
+ end # def to_hash
71
+
72
+ # return true if the node is all set to connect using ssh user and password.
73
+ def using_password?
74
+ !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_password.nil?
75
+ end
76
+
77
+ # return true if the node is all set to connect using a private key file.
78
+ def using_private_key_file?
79
+ !self.net_remote_ip.nil? && !self.ssh_username.nil? && !self.ssh_private_key_file.nil?
80
+ end
81
+
82
+ def connect
83
+ # connect
84
+ if self.using_password?
85
+ self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :password => self.ssh_password, :port => self.ssh_port)
86
+ elsif self.using_private_key_file?
87
+ self.ssh = Net::SSH.start(self.net_remote_ip, self.ssh_username, :keys => self.ssh_private_key_file, :port => self.ssh_port)
88
+ else
89
+ raise "No ssh credentials available"
90
+ end
91
+ self.ssh
92
+ end # def connect
93
+
94
+ def disconnect
95
+ self.ssh.close
96
+ end
97
+
98
+ def exec(command)
99
+ s = nil
100
+ if self.using_password?
101
+ s = self.ssh.exec!("echo '#{self.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c '#{command.gsub("'", "\\'")}'")
102
+ elsif self.using_private_key_file?
103
+ s = self.ssh.exec!("sudo -S su root -c '#{command.gsub("'", "\\'")}'")
104
+ end
105
+ s
106
+ end # def exec
107
+
108
+ def reboot()
109
+ tries = 0
110
+ max_tries = 20
111
+ success = false
112
+
113
+ host = self
114
+
115
+ logger.logs 'reboot... '
116
+ #stdout = host.reboot
117
+ begin
118
+ stdout = host.ssh.exec!("echo '#{host.ssh_password.gsub("'", "\\'")}' | sudo -S su root -c 'reboot'")
119
+ rescue
120
+ end
121
+ logger.done #logf("done (#{stdout})")
122
+
123
+ while tries < max_tries && !success
124
+ begin
125
+ tries += 1
126
+
127
+ delay = 10
128
+ logger.logs "wait #{delay.to_s} seconds... "
129
+ sleep(delay)
130
+ logger.done
131
+
132
+ logger.logs "connecting (try #{tries.to_s})... "
133
+ host.connect
134
+ logger.done
135
+
136
+ success = true
137
+ rescue => e
138
+ logger.logf e.to_s #error e
139
+ end
140
+ end # while
141
+ raise 'reboot failed' if !success
142
+ end # def reboot
143
+
144
+ end # module NodeModule
145
+
146
+ # TODO: declare these classes (stub and skeleton) using blackstack-rpc
147
+ #
148
+ # Node Stub
149
+ # This class represents a node, without using connection to the database.
150
+ # Use this class at the client side.
151
+ class Node
152
+ # :name is this is just a descriptive name for the node. It is not the host name, nor the domain, nor any ip.
153
+ attr_accessor :name, :net_remote_ip, :ssh_username, :ssh_password, :ssh_port, :ssh_private_key_file
154
+ include NodeModule
155
+ end # class Node
156
+ =begin
157
+ # Node Skeleton
158
+ # This class represents a node, with connection to the database.
159
+ # Use this class at the server side.
160
+ class Node < Sequel::Model(:node)
161
+ include NodeModule
162
+ end
163
+ =end
164
+ end # module Infrastructure
165
+ end # module BlackStack
metadata ADDED
@@ -0,0 +1,89 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: blackstack-nodes
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Leandro Daniel Sardi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-05-30 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: net-ssh
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 6.1.0
20
+ - - ">="
21
+ - !ruby/object:Gem::Version
22
+ version: 6.1.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: 6.1.0
30
+ - - ">="
31
+ - !ruby/object:Gem::Version
32
+ version: 6.1.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: simple_cloud_logging
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - "~>"
38
+ - !ruby/object:Gem::Version
39
+ version: 1.2.2
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ version: 1.2.2
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - "~>"
48
+ - !ruby/object:Gem::Version
49
+ version: 1.2.2
50
+ - - ">="
51
+ - !ruby/object:Gem::Version
52
+ version: 1.2.2
53
+ description: "BlackStack Nodes is a simple library to managing a computer remotely
54
+ via SSH, and perform some common operations.\nThis library is used and extended
55
+ by many others like: \n- [BlackStack Deployer](https://github.com/leandrosardi/blackstack-deployer)\n-
56
+ [Pampa](https://github.com/leandrosardi/pampa)\n- [Simple Proxies Monitoring](https://github.com/leandrosardi/simple_proxies_deploying)\n-
57
+ [Simple Hosts Monitoring](https://github.com/leandrosardi/simple_host_monitoring)
58
+ \ \n"
59
+ email: leandro.sardi@expandedventure.com
60
+ executables: []
61
+ extensions: []
62
+ extra_rdoc_files: []
63
+ files:
64
+ - lib/blackstack-nodes.rb
65
+ homepage: https://rubygems.org/gems/blackstack-nodes
66
+ licenses:
67
+ - MIT
68
+ metadata: {}
69
+ post_install_message:
70
+ rdoc_options: []
71
+ require_paths:
72
+ - lib
73
+ required_ruby_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ required_rubygems_version: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ requirements: []
84
+ rubygems_version: 3.3.7
85
+ signing_key:
86
+ specification_version: 4
87
+ summary: BlackStack Nodes is a simple library to managing a computer remotely via
88
+ SSH, and perform some common operations.
89
+ test_files: []