/
irmc-auto-discovery.py
155 lines (130 loc) · 5.29 KB
/
irmc-auto-discovery.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#!/usr/bin/env python
# -*- coding: utf-8 -*-
'''
Sample script to search/configure iRMC on the network via SSDP and Redfish
Copyright (C) 2020 Masahiro Murayama
[Usage]
- List discovered system on the network
$ python ./irmc-auto-discovery.py show
- Set the IPv4 address/netmask/gateway to the target iRMC
$ python ./irmc-auto-discovery.py configure -s <serial number> -i <ip address> -m <netmask> -g <gateway>
'''
import sys
import socket
import argparse
import json
import requests
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
def discover_irmc():
message = \
'M-SEARCH * HTTP/1.1\r\n' \
'HOST:[ff02::c]:1900\r\n' \
'ST: urn:dmtf-org:service:redfish-rest:1\r\n' \
'MX:3\r\n' \
'MAN:"ssdp:discover"\r\n' \
'\r\n'
s = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
s.settimeout(4)
s.sendto(bytes(message, 'UTF-8'), ('ff02::c', 1900))
url_set = set()
try:
while True:
data, addr = s.recvfrom(65507)
# print(data)
# print(addr)
url_set.add('https://[{}]/redfish/v1/'.format(addr[0]))
except socket.timeout:
pass
return url_set
def show_info(url_set, user, password):
for url in url_set:
try:
headers = {'Accept': 'application/json',
'Content-Type': 'application/json'}
response = requests.get(url, headers=headers, verify=False)
model = response.json()['Oem']['ts_fujitsu']['AutoDiscoveryDescription']['ServerNodeInformation']['Model']
sn = response.json()['Oem']['ts_fujitsu']['AutoDiscoveryDescription']['ServerNodeInformation']['SerialNumber']
response = requests.get(url + "Managers/iRMC/Oem/ts_fujitsu/iRMCConfiguration/Lan",
headers=headers, auth=(user, password), verify=False)
ipv4_addr = response.json()['IpV4']['IpAddress']
ipv4_dhcp = response.json()['IpV4']['UseDhcp']
print("Model: {0}, S/N: {1}, IPv4: {2}".format(model, sn, ipv4_addr))
except Exception as e:
print(e)
def configure_irmc(user, password, serial, address, netmask, gateway):
urls = discover_irmc()
for url in urls:
try:
headers = {'Accept': 'application/json',
'Content-Type': 'application/json'}
response = requests.get(url, headers=headers, verify=False)
if response.json()['Oem']['ts_fujitsu']['AutoDiscoveryDescription']['ServerNodeInformation']['SerialNumber'] == serial:
response = requests.get(url + "Managers/iRMC/Oem/ts_fujitsu/iRMCConfiguration/Lan",
headers=headers, auth=(user, password), verify=False)
etag = response.json()['@odata.etag']
headers = {
'Accept': 'application/json',
'Content-Type': 'application/json',
'If-Match': etag
}
payload = {
'IpV4': {
'UseDhcp': 'false',
'IpAddress': address,
'SubnetMask': netmask,
'DefaultGateway': gateway,
}
}
response = requests.patch(url + "Managers/iRMC/Oem/ts_fujitsu/iRMCConfiguration/Lan",
headers=headers, auth=(user, password), data=json.dumps(payload), verify=False)
if response.status_code == 200:
print("The iRMC network has been configured successfully. Please wait for a few minutes for iRMC to activate the new configuration.")
else:
print("The request failed (error: {0})".format(response.json()['error']['message']))
break
except Exception as e:
print(e)
def main():
parser = argparse.ArgumentParser()
parser.add_argument(
'action',
choices=['show', 'configure'],
help="show or configure. if configure is specified, Must use with -a, -m, and -g.")
parser.add_argument(
'-u', '--user',
default="admin",
help="iRMC user name")
parser.add_argument(
'-p', '--password',
default="admin",
help="iRMC password")
parser.add_argument(
'-a', '--address',
help="IPv4 address")
parser.add_argument(
'-m', '--netmask',
help="Netmask")
parser.add_argument(
'-g', '--gateway',
help="Gateway")
parser.add_argument(
'-s', '--serial',
help="System serial number")
args = parser.parse_args()
user = args.user
password = args.password
if args.action == 'show':
show_info(discover_irmc(), user, password)
elif args.action == 'configure':
address = args.address
netmask = args.netmask
gateway = args.gateway
serial = args.serial
if address is not None and netmask is not None and gateway is not None and serial is not None:
configure_irmc(user, password, serial, address, netmask, gateway)
else:
print("ERROR: '-a', '-m', '-g', and '-s' must be specified.")
sys.exit()
if __name__ == '__main__':
main()