supermicro 0.1.6 → 0.1.7
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.
- checksums.yaml +4 -4
- data/lib/supermicro/network.rb +126 -4
- data/lib/supermicro/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7b045637afdfc22ca25c75e6acd7cf8880a8b8fcd55db67a3aebf5bc8e7875c
|
4
|
+
data.tar.gz: 90f5b3cae2874bb7511e087b03cd4940e1b2594ddafed3f864aa486fdd7abc2a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: '0835ab4b24a469bc013afba3f514f66b86d15d1578785284d2007720aa4065b84db873a49d5c8de9447ce47329926fa9ec13794995916569d8258b495cc0bd0f'
|
7
|
+
data.tar.gz: 430d94eda6451653864324f62002cb42e9ce15e7b7bb27f27a222ce3e24f59b369b3870a253f08ef478a899dcbf13f16c444ece56e1cb0e2b17972ca7a5fe954
|
data/lib/supermicro/network.rb
CHANGED
@@ -27,7 +27,7 @@ module Supermicro
|
|
27
27
|
|
28
28
|
def set_bmc_network(ip_address: nil, subnet_mask: nil, gateway: nil,
|
29
29
|
dns_primary: nil, dns_secondary: nil, hostname: nil,
|
30
|
-
dhcp: false)
|
30
|
+
dhcp: false, wait: true)
|
31
31
|
|
32
32
|
if dhcp
|
33
33
|
puts "Setting BMC to DHCP mode...".yellow
|
@@ -42,6 +42,8 @@ module Supermicro
|
|
42
42
|
|
43
43
|
# Configure static IP if provided
|
44
44
|
if ip_address && subnet_mask
|
45
|
+
# Must explicitly disable DHCP when setting static IP
|
46
|
+
body["DHCPv4"] = { "DHCPEnabled" => false }
|
45
47
|
body["IPv4StaticAddresses"] = [{
|
46
48
|
"Address" => ip_address,
|
47
49
|
"SubnetMask" => subnet_mask,
|
@@ -75,9 +77,43 @@ module Supermicro
|
|
75
77
|
)
|
76
78
|
|
77
79
|
if response.status.between?(200, 299)
|
78
|
-
puts "BMC network
|
79
|
-
|
80
|
-
|
80
|
+
puts "BMC network configuration submitted.".green
|
81
|
+
|
82
|
+
# If we're changing IP and wait is enabled, handle the transition
|
83
|
+
if ip_address && wait
|
84
|
+
puts "Waiting for BMC to apply network changes...".yellow
|
85
|
+
|
86
|
+
# Check if response contains a task/job ID
|
87
|
+
if response.status == 202 && response.headers['Location']
|
88
|
+
# Job was created, monitor it
|
89
|
+
job_uri = response.headers['Location']
|
90
|
+
puts "Monitoring job: #{job_uri}".cyan
|
91
|
+
|
92
|
+
# Wait for current job to complete (on old IP)
|
93
|
+
wait_for_network_job(job_uri)
|
94
|
+
else
|
95
|
+
# No job, just wait a bit for the change to apply
|
96
|
+
sleep 5
|
97
|
+
end
|
98
|
+
|
99
|
+
# Now verify the BMC is reachable on the new IP
|
100
|
+
puts "Verifying BMC is reachable on new IP: #{ip_address}...".yellow
|
101
|
+
if verify_bmc_on_new_ip(ip_address, @username, @password)
|
102
|
+
puts "BMC successfully configured and reachable on #{ip_address}".green
|
103
|
+
|
104
|
+
# Update our client's host to the new IP
|
105
|
+
@host = ip_address
|
106
|
+
true
|
107
|
+
else
|
108
|
+
puts "WARNING: BMC configuration may have succeeded but cannot reach BMC on #{ip_address}".yellow
|
109
|
+
puts "The BMC may still be applying changes or may require manual verification.".yellow
|
110
|
+
false
|
111
|
+
end
|
112
|
+
else
|
113
|
+
puts "BMC network configured successfully.".green
|
114
|
+
puts "WARNING: BMC may restart network services. Connection may be lost.".yellow if ip_address && !wait
|
115
|
+
true
|
116
|
+
end
|
81
117
|
else
|
82
118
|
raise Error, "Failed to configure BMC network: #{response.status} - #{response.body}"
|
83
119
|
end
|
@@ -87,5 +123,91 @@ module Supermicro
|
|
87
123
|
# Convenience method
|
88
124
|
set_bmc_network(dhcp: true)
|
89
125
|
end
|
126
|
+
|
127
|
+
private
|
128
|
+
|
129
|
+
def wait_for_network_job(job_uri, timeout: 60)
|
130
|
+
start_time = Time.now
|
131
|
+
|
132
|
+
while (Time.now - start_time) < timeout
|
133
|
+
begin
|
134
|
+
response = authenticated_request(:get, job_uri)
|
135
|
+
|
136
|
+
if response.status == 200
|
137
|
+
data = JSON.parse(response.body)
|
138
|
+
state = data["TaskState"] || data["JobState"] || "Unknown"
|
139
|
+
|
140
|
+
case state
|
141
|
+
when "Completed", "OK"
|
142
|
+
puts "Network configuration job completed successfully.".green
|
143
|
+
return true
|
144
|
+
when "Exception", "Critical", "Error", "Failed"
|
145
|
+
puts "Network configuration job failed: #{state}".red
|
146
|
+
return false
|
147
|
+
else
|
148
|
+
print "."
|
149
|
+
sleep 2
|
150
|
+
end
|
151
|
+
else
|
152
|
+
# Can't check status, assume it's applying
|
153
|
+
sleep 2
|
154
|
+
end
|
155
|
+
rescue => e
|
156
|
+
# Connection might be interrupted during network change
|
157
|
+
debug "Connection error during job monitoring (expected): #{e.message}", 2
|
158
|
+
sleep 2
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
puts "\nJob monitoring timed out after #{timeout} seconds".yellow
|
163
|
+
false
|
164
|
+
end
|
165
|
+
|
166
|
+
def verify_bmc_on_new_ip(new_ip, username, password, retries: 10, delay: 3)
|
167
|
+
retries.times do |i|
|
168
|
+
begin
|
169
|
+
# Create a new connection to test the new IP
|
170
|
+
test_conn = Faraday.new(
|
171
|
+
url: "https://#{new_ip}",
|
172
|
+
ssl: { verify: @verify_ssl }
|
173
|
+
) do |f|
|
174
|
+
f.adapter Faraday.default_adapter
|
175
|
+
f.response :follow_redirects
|
176
|
+
end
|
177
|
+
|
178
|
+
# Try to access the Redfish root
|
179
|
+
response = test_conn.get('/redfish/v1/')
|
180
|
+
|
181
|
+
if response.status == 200 || response.status == 401
|
182
|
+
# BMC is responding, try to login
|
183
|
+
login_response = test_conn.post do |req|
|
184
|
+
req.url '/redfish/v1/SessionService/Sessions'
|
185
|
+
req.headers['Content-Type'] = 'application/json'
|
186
|
+
req.body = {
|
187
|
+
"UserName" => username,
|
188
|
+
"Password" => password
|
189
|
+
}.to_json
|
190
|
+
end
|
191
|
+
|
192
|
+
if login_response.status.between?(200, 204)
|
193
|
+
# Successfully reached and authenticated
|
194
|
+
# Clean up the test session
|
195
|
+
if login_response.headers['x-auth-token']
|
196
|
+
test_conn.delete('/redfish/v1/SessionService/Sessions') do |req|
|
197
|
+
req.headers['X-Auth-Token'] = login_response.headers['x-auth-token']
|
198
|
+
end
|
199
|
+
end
|
200
|
+
return true
|
201
|
+
end
|
202
|
+
end
|
203
|
+
rescue => e
|
204
|
+
debug "Attempt #{i+1}/#{retries} failed: #{e.message}", 2
|
205
|
+
end
|
206
|
+
|
207
|
+
sleep delay unless i == retries - 1
|
208
|
+
end
|
209
|
+
|
210
|
+
false
|
211
|
+
end
|
90
212
|
end
|
91
213
|
end
|
data/lib/supermicro/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: supermicro
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Siegel
|
@@ -187,7 +187,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
187
187
|
- !ruby/object:Gem::Version
|
188
188
|
version: '0'
|
189
189
|
requirements: []
|
190
|
-
rubygems_version: 3.
|
190
|
+
rubygems_version: 3.5.22
|
191
191
|
signing_key:
|
192
192
|
specification_version: 4
|
193
193
|
summary: API Client for Supermicro BMC
|