1""" 2Manage IPMI devices over LAN 3============================ 4 5The following configuration defaults can be defined in the 6minion, master config or pillar: 7 8.. code-block:: yaml 9 10 ipmi.config: 11 api_host: 127.0.0.1 12 api_user: admin 13 api_pass: apassword 14 api_port: 623 15 api_kg: None 16 17Every call can override the config defaults: 18 19.. code-block:: yaml 20 21 ensure myipmi system is set to network boot: 22 ipmi.boot_device: 23 - name: network 24 - api_host: myipmi.hostname.com 25 - api_user: root 26 - api_pass: apassword 27 - api_kg: None 28 29 ensure myipmi system is powered on: 30 ipmi.power: 31 - name: boot 32 - api_host: myipmi.hostname.com 33 - api_user: root 34 - api_pass: apassword 35""" 36 37 38def __virtual__(): 39 IMPORT_ERR = None 40 try: 41 from pyghmi.ipmi import command # pylint: disable=unused-import 42 except Exception as exc: # pylint: disable=broad-except 43 IMPORT_ERR = str(exc) 44 return (IMPORT_ERR is None, IMPORT_ERR) 45 46 47def boot_device(name="default", **kwargs): 48 """ 49 Request power state change 50 51 name = ``default`` 52 * network -- Request network boot 53 * hd -- Boot from hard drive 54 * safe -- Boot from hard drive, requesting 'safe mode' 55 * optical -- boot from CD/DVD/BD drive 56 * setup -- Boot into setup utility 57 * default -- remove any IPMI directed boot device request 58 59 kwargs 60 - api_host=localhost 61 - api_user=admin 62 - api_pass= 63 - api_port=623 64 - api_kg=None 65 """ 66 ret = {"name": name, "result": False, "comment": "", "changes": {}} 67 org = __salt__["ipmi.get_bootdev"](**kwargs) 68 if "bootdev" in org: 69 org = org["bootdev"] 70 71 if org == name: 72 ret["result"] = True 73 ret["comment"] = "system already in this state" 74 return ret 75 76 if __opts__["test"]: 77 ret["comment"] = "would change boot device" 78 ret["result"] = None 79 ret["changes"] = {"old": org, "new": name} 80 return ret 81 82 outdddd = __salt__["ipmi.set_bootdev"](bootdev=name, **kwargs) 83 ret["comment"] = "changed boot device" 84 ret["result"] = True 85 ret["changes"] = {"old": org, "new": name} 86 return ret 87 88 89def power(name="power_on", wait=300, **kwargs): 90 """ 91 Request power state change 92 93 name 94 Ensure power state one of: 95 * power_on -- system turn on 96 * power_off -- system turn off (without waiting for OS) 97 * shutdown -- request OS proper shutdown 98 * reset -- reset (without waiting for OS) 99 * boot -- If system is off, then 'on', else 'reset' 100 101 wait 102 wait X seconds for the job to complete before forcing. 103 (defaults to 300 seconds) 104 105 kwargs 106 - api_host=localhost 107 - api_user=admin 108 - api_pass= 109 - api_port=623 110 - api_kg=None 111 """ 112 ret = {"name": name, "result": False, "comment": "", "changes": {}} 113 org = __salt__["ipmi.get_power"](**kwargs) 114 115 state_map = { 116 "off": "off", 117 "on": "on", 118 "power_off": "off", 119 "power_on": "on", 120 "shutdown": "off", 121 "reset": "na", 122 "boot": "na", 123 } 124 125 if org == state_map[name]: 126 ret["result"] = True 127 ret["comment"] = "system already in this state" 128 return ret 129 130 if __opts__["test"]: 131 ret["comment"] = "would power: {} system".format(name) 132 ret["result"] = None 133 ret["changes"] = {"old": org, "new": name} 134 return ret 135 136 outdddd = __salt__["ipmi.set_power"](name, wait=wait, **kwargs) 137 ret["comment"] = "changed system power" 138 ret["result"] = True 139 ret["changes"] = {"old": org, "new": name} 140 return ret 141 142 143def user_present( 144 name, 145 uid, 146 password, 147 channel=14, 148 callback=False, 149 link_auth=True, 150 ipmi_msg=True, 151 privilege_level="administrator", 152 **kwargs 153): 154 """ 155 Ensure IPMI user and user privileges. 156 157 name 158 name of user (limit 16 bytes) 159 160 uid 161 user id number (1 to 7) 162 163 password 164 user password (limit 16 bytes) 165 166 channel 167 ipmi channel defaults to 14 for auto 168 169 callback 170 User Restricted to Callback 171 172 False = User Privilege Limit is determined by the User Privilege Limit 173 parameter privilege_level, for both callback and non-callback connections. 174 175 True = User Privilege Limit is determined by the privilege_level 176 parameter for callback connections, but is restricted to Callback 177 level for non-callback connections. Thus, a user can only initiate 178 a Callback when they 'call in' to the BMC, but once the callback 179 connection has been made, the user could potentially establish a 180 session as an Operator. 181 182 link_auth 183 User Link authentication 184 True/False 185 user name and password information will be used for link 186 authentication, e.g. PPP CHAP) for the given channel. Link 187 authentication itself is a global setting for the channel and is 188 enabled/disabled via the serial/modem configuration parameters. 189 190 ipmi_msg 191 User IPMI Messaging 192 True/False 193 user name and password information will be used for IPMI 194 Messaging. In this case, 'IPMI Messaging' refers to the ability to 195 execute generic IPMI commands that are not associated with a 196 particular payload type. For example, if IPMI Messaging is disabled for 197 a user, but that user is enabled for activating the SOL 198 payload type, then IPMI commands associated with SOL and session 199 management, such as Get SOL Configuration Parameters and Close Session 200 are available, but generic IPMI commands such as Get SEL Time are 201 unavailable.) 202 ipmi_msg 203 204 privilege_level 205 * callback 206 * user 207 * operator 208 * administrator 209 * proprietary 210 * no_access 211 212 kwargs 213 - api_host=localhost 214 - api_user=admin 215 - api_pass= 216 - api_port=623 217 - api_kg=None 218 """ 219 ret = {"name": name, "result": False, "comment": "", "changes": {}} 220 org_user = __salt__["ipmi.get_user"](uid=uid, channel=channel, **kwargs) 221 222 change = False 223 if org_user["access"]["callback"] != callback: 224 change = True 225 if org_user["access"]["link_auth"] != link_auth: 226 change = True 227 if org_user["access"]["ipmi_msg"] != ipmi_msg: 228 change = True 229 if org_user["access"]["privilege_level"] != privilege_level: 230 change = True 231 if ( 232 __salt__["ipmi.set_user_password"]( 233 uid, mode="test_password", password=password, **kwargs 234 ) 235 is False 236 ): 237 change = True 238 239 if change is False: 240 ret["result"] = True 241 ret["comment"] = "user already present" 242 return ret 243 244 if __opts__["test"]: 245 ret["comment"] = "would (re)create user" 246 ret["result"] = None 247 ret["changes"] = {"old": org_user, "new": name} 248 return ret 249 250 __salt__["ipmi.ensure_user"]( 251 uid, 252 name, 253 password, 254 channel, 255 callback, 256 link_auth, 257 ipmi_msg, 258 privilege_level, 259 **kwargs 260 ) 261 current_user = __salt__["ipmi.get_user"](uid=uid, channel=channel, **kwargs) 262 ret["comment"] = "(re)created user" 263 ret["result"] = True 264 ret["changes"] = {"old": org_user, "new": current_user} 265 return ret 266 267 268def user_absent(name, channel=14, **kwargs): 269 """ 270 Remove user 271 Delete all user (uid) records having the matching name. 272 273 name 274 string name of user to delete 275 276 channel 277 channel to remove user access from defaults to 14 for auto. 278 279 kwargs 280 - api_host=localhost 281 - api_user=admin 282 - api_pass= 283 - api_port=623 284 - api_kg=None 285 """ 286 ret = {"name": name, "result": False, "comment": "", "changes": {}} 287 user_id_list = __salt__["ipmi.get_name_uids"](name, channel, **kwargs) 288 289 if len(user_id_list) == 0: 290 ret["result"] = True 291 ret["comment"] = "user already absent" 292 return ret 293 294 if __opts__["test"]: 295 ret["comment"] = "would delete user(s)" 296 ret["result"] = None 297 ret["changes"] = {"delete": user_id_list} 298 return ret 299 300 for uid in user_id_list: 301 __salt__["ipmi.delete_user"](uid, channel, **kwargs) 302 303 ret["comment"] = "user(s) removed" 304 ret["changes"] = {"old": user_id_list, "new": "None"} 305 return ret 306