blackstack-nodes 1.2.1

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 +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: []