Index: luci/cluster/fence-macros =================================================================== RCS file: /cvs/cluster/conga/luci/cluster/fence-macros,v retrieving revision 1.2.2.17 diff -u -r1.2.2.17 fence-macros --- a/luci/cluster/fence-macros 7 Aug 2010 04:11:22 -0000 1.2.2.17 +++ b/luci/cluster/fence-macros 31 Aug 2010 20:01:36 -0000 @@ -10,7 +10,7 @@ <html> <head> - <title tal:content="string:" /> + <title tal:content="string:" /> </head> <body> @@ -254,6 +254,10 @@ <tal:block metal:use-macro="here/fence-macros/macros/fence-form-scsi" /> </tal:block> + <tal:block tal:condition="python: cur_fence_type == 'fence_cisco_mds'"> + <tal:block metal:use-macro="here/fence-macros/macros/fence-form-cisco_mds" /> + </tal:block> + <tal:block tal:condition="python: cur_fence_type == 'fence_manual'"> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-manual" /> </tal:block> @@ -339,6 +343,7 @@ <option name="fence_scsi" value="fence_scsi">SCSI Fencing</option> <option name="fence_vmware" value="fence_vmware">VMware Fencing</option> <option name="fence_lpar" value="fence_lpar">LPAR Fencing</option> + <option name="fence_cisco_mds" value="fence_cisco_mds">Cisco MDS</option> </div> <div metal:define-macro="fence-option-list"> @@ -363,6 +368,7 @@ <option name="fence_scsi" value="fence_scsi">SCSI Fencing</option> <option name="fence_vmware" value="fence_vmware">VMware Fencing</option> <option name="fence_lpar" value="fence_lpar">LPAR Fencing</option> + <option name="fence_cisco_mds" value="fence_cisco_mds">Cisco MDS</option> <option name="fence_manual" value="fence_manual">Manual Fencing</option> </div> @@ -1727,6 +1733,209 @@ </div> </div> +<div metal:define-macro="fence-form-cisco_mds" + tal:attributes="id cur_fencedev/name | nothing"> + + <div id="fence_cisco_mds" class="fencedev"> + <table> + <tr> + <td><strong class="cluster">Fence Type</strong></td> + <td>Cisco MDS</td> + </tr> + <tr> + <td>Name</td> + <td> + <input name="name" type="text" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/name | nothing" /> + </td> + </tr> + <tr> + <td>IP address or hostname</td> + <td> + <input name="ipaddr" type="text" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/ipaddr | nothing" /> + </td> + </tr> + <tr> + <td>UDP/TCP port (optional, defaults to 161)</td> + <td> + <input name="udpport" type="text" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/udpport | nothing" /> + </td> + </tr> + <tr> + <td>Login</td> + <td> + <input name="login" type="text" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/login | nothing" /> + </td> + </tr> + <tr> + <td>Password</td> + <td> + <input name="passwd" type="password" autocomplete="off" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/passwd | nothing" /> + </td> + </tr> + <tr> + <td> + <span title="Full path to a script to generate fence password">Password Script (optional)</span> + </td> + <td> + <input type="text" name="passwd_script" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/passwd_script | nothing" /> + </td> + </tr> + <tr> + <td>SNMP version</td> + <td> + <select name="snmp_version" + tal:define="snmp_version cur_fencedev/snmp_version | string:default" + tal:attributes="disabled cur_fencedev/isShared | nothing"> + <option value="" + tal:content="string:Default" + tal:attributes="selected python: snmp_version == 'default' and 'selected'"/> + <option value="1" + tal:content="string:1" + tal:attributes="selected python: snmp_version == '1' and 'selected'"/> + <option value="2c" + tal:content="string:2c" + tal:attributes="selected python: snmp_version == '2c' and 'selected'"/> + <option value="3" + tal:content="string:3" + tal:attributes="selected python: snmp_version == '3' and 'selected'"/> + </select> + </td> + </tr> + <tr> + <td>SNMP community</td> + <td> + <input name="community" type="text" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/community | nothing" /> + </td> + </tr> + <tr> + <td>SNMP security level</td> + <td> + <select name="snmp_sec_level" + tal:define="snmp_sec_level cur_fencedev/snmp_sec_level | string:default" + tal:attributes="disabled cur_fencedev/isShared | nothing"> + <option value="" + tal:content="string:Default" + tal:attributes="selected python: snmp_sec_level == 'default' and 'selected'"/> + + <option value="noAuthNoPriv" + tal:content="string:noAuthNoPriv" + tal:attributes="selected python: snmp_sec_level == 'noAuthNoPriv' and 'selected'"/> + + <option value="authNoPriv" + tal:content="string:authNoPriv" + tal:attributes="selected python: snmp_sec_level == 'authNoPriv' and 'selected'"/> + + <option value="authPriv" + tal:content="string:authPriv" + tal:attributes="selected python: snmp_sec_level == 'authPriv' and 'selected'"/> + </select> + </td> + </tr> + <tr> + <td>SNMP authentication protocol</td> + <td> + <select name="snmp_auth_prot" + tal:define="snmp_auth_prot cur_fencedev/snmp_auth_prot | string:default" + tal:attributes="disabled cur_fencedev/isShared | nothing"> + <option value="" + tal:content="string:Default" + tal:attributes="selected python: snmp_auth_prot == 'default' and 'selected'"/> + + <option value="" + tal:content="string:Default" + tal:attributes="selected python: snmp_auth_prot == 'default' and 'selected'"/> + + <option value="MD5" + tal:content="string:MD5" + tal:attributes="selected python: snmp_auth_prot == 'MD5' and 'selected'"/> + + <option value="SHA" + tal:content="string:SHA" + tal:attributes="selected python: snmp_auth_prot == 'SHA' and 'selected'"/> + </select> + </td> + </tr> + <tr> + <td>SNMP privacy protocol</td> + <td> + <select name="snmp_priv_prot" + tal:define="snmp_priv_prot cur_fencedev/snmp_priv_prot | string:default" + tal:attributes="disabled cur_fencedev/isShared | nothing"> + <option value="" + tal:content="string:Default" + tal:attributes="selected python: snmp_priv_prot == 'default' and 'selected'"/> + <option value="DES" + tal:content="string:DES" + tal:attributes="selected python: snmp_priv_prot == 'DES' and 'selected'"/> + <option value="AES" + tal:content="string:AES" + tal:attributes="selected python: snmp_priv_prot == 'AES' and 'selected'"/> + </select> + </td> + </tr> + <tr> + <td>SNMP privacy protocol password</td> + <td> + <input name="snmp_priv_passwd" type="password" autocomplete="off" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/snmp_priv_passwd | nothing" /> + </td> + </tr> + <tr> + <td> + SNMP privacy protocol script + </td> + <td> + <input type="text" name="snmp_priv_passwd_script" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/snmp_priv_passwd_script | nothing" /> + </td> + </tr> + <tr> + <td>Power wait (seconds)</td> + <td> + <input type="text" name="power_wait" + tal:attributes=" + disabled cur_fencedev/isShared | nothing; + value cur_fencedev/power_wait | nothing" /> + </td> + </tr> + </table> + + <tal:block tal:condition="exists: cur_fencedev"> + <input type="hidden" name="existing_device" value="1" /> + <input type="hidden" name="orig_name" + tal:attributes="value cur_fencedev/name | nothing" /> + </tal:block> + + <input type="hidden" name="sharable" value="1" /> + <input type="hidden" name="fence_type" value="fence_cisco_mds" /> + </div> +</div> + <div metal:define-macro="fence-form-list"> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-apc" /> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-mcdata" /> @@ -1748,6 +1957,7 @@ <tal:block metal:use-macro="here/fence-macros/macros/fence-form-scsi" /> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-lpar" /> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-vmware" /> + <tal:block metal:use-macro="here/fence-macros/macros/fence-form-cisco_mds" /> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-manual" /> </div> @@ -1766,6 +1976,7 @@ <tal:block metal:use-macro="here/fence-macros/macros/fence-form-scsi" /> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-lpar" /> <tal:block metal:use-macro="here/fence-macros/macros/fence-form-vmware" /> + <tal:block metal:use-macro="here/fence-macros/macros/fence-form-cisco_mds" /> </div> <div metal:define-macro="shared-fence-device-list"> @@ -2377,6 +2588,44 @@ </div> </div> +<div metal:define-macro="fence-instance-form-cisco_mds" + tal:omit-tag="exists: cur_fence_dev_id"> + <div id="fence_cisco_mds_instance" name="fence_cisco_mds" class="fencedev_instance" + tal:omit-tag="exists: cur_fence_dev_id"> + <table> + <tr> + <td>Port</td> + <td> + <input name="port" type="text" + tal:attributes="value cur_instance/port | nothing" /> + </td> + </tr> + <tr><td colspan="2"> + <div class="hbSubmit"> + <tal:block tal:condition="exists:cur_fence_instance_id"> + <input type="button" name="remove_fence" + value="Remove this instance" + tal:attributes="onclick python: 'del_fence_instance(\'' + cur_fence_instance_id + '\')'" /> + </tal:block> + <tal:block tal:condition="not:exists:cur_fence_instance_id"> + <input type="button" name="remove_fence" + value="Remove this instance" /> + </tal:block> + </div> + </td></tr> + </table> + + <input type="hidden" name="option" tal:condition="exists:cur_instance" + tal:attributes="value cur_instance/option |nothing" /> + <input type="hidden" name="fence_type" value="fence_cisco_mds" /> + <input type="hidden" name="fence_instance" value="1" /> + <input tal:condition="exists: cur_instance" + type="hidden" name="existing_instance" value="1" /> + <input type="hidden" name="parent_fencedev" + tal:attributes="value cur_fence_dev_id | nothing" /> + </div> +</div> + <div metal:define-macro="fence-instance-form-list"> <tal:block metal:use-macro="here/fence-macros/macros/fence-instance-form-apc" /> @@ -2406,6 +2655,8 @@ metal:use-macro="here/fence-macros/macros/fence-instance-form-xvm" /> <tal:block metal:use-macro="here/fence-macros/macros/fence-instance-form-bladecenter" /> + <tal:block + metal:use-macro="here/fence-macros/macros/fence-instance-form-cisco_mds" /> </div> <div metal:define-macro="fencedev-instance-cond-ladder" @@ -2480,6 +2731,11 @@ <tal:block metal:use-macro="here/fence-macros/macros/fence-instance-form-bladecenter" /> </tal:block> + + <tal:block tal:condition="python: cur_fence_type == 'fence_cisco_mds'"> + <tal:block + metal:use-macro="here/fence-macros/macros/fence-instance-form-cisco_mds" /> + </tal:block> </div> </body> Index: luci/cluster/validate_fence.js =================================================================== RCS file: /cvs/cluster/conga/luci/cluster/validate_fence.js,v retrieving revision 1.1.2.13 diff -u -r1.1.2.13 validate_fence.js --- a/luci/cluster/validate_fence.js 5 Aug 2010 17:33:05 -0000 1.1.2.13 +++ b/luci/cluster/validate_fence.js 31 Aug 2010 20:01:36 -0000 @@ -22,6 +22,7 @@ fence_inst_validator['xvm'] = [ 'domain' ]; fence_inst_validator['lpar'] = [ 'partition', 'managed' ]; fence_inst_validator['vmware'] = [ 'port' ]; +fence_inst_validator['cisco_mds'] = [ 'port' ]; var fence_validator = []; fence_validator['apc'] = [ 'ipaddr', 'login', 'passwd', 'passwd_script' ]; @@ -44,6 +45,7 @@ fence_validator['vixel'] = [ 'ipaddr', 'passwd', 'passwd_script' ]; fence_validator['wti'] = [ 'ipaddr', 'passwd', 'passwd_script' ]; fence_validator['lpar'] = [ 'ipaddr', 'login', 'passwd', 'passwd_script' ]; +fence_validator['cisco_mds'] = [ 'ipaddr', 'login', 'passwd', 'passwd_script' ]; fence_validator['vmware'] = [ 'ipaddr', 'login', 'passwd', 'passwd_script', 'vmlogin' ]; fence_validator['xvm'] = []; Index: luci/site/luci/Extensions/FenceHandler.py =================================================================== RCS file: /cvs/cluster/conga/luci/site/luci/Extensions/FenceHandler.py,v retrieving revision 1.4.2.22 diff -u -r1.4.2.22 FenceHandler.py --- a/luci/site/luci/Extensions/FenceHandler.py 7 Aug 2010 04:11:22 -0000 1.4.2.22 +++ b/luci/site/luci/Extensions/FenceHandler.py 31 Aug 2010 20:01:38 -0000 @@ -776,6 +776,176 @@ return errors +def val_cisco_mds_fd(form, fencedev): + errors = list() + + try: + ip = form['ipaddr'].strip() + if not ip: + raise Exception, 'blank' + fencedev.addAttribute('ipaddr', ip) + except Exception, e: + errors.append(FD_PROVIDE_IP) + + try: + log = form['login'].strip() + if not log: + raise Exception, 'blank' + fencedev.addAttribute('login', log) + except Exception, e: + errors.append(FD_PROVIDE_LOGIN) + + try: + power_wait = form['power_wait'].strip() + if power_wait: + power_wait = int(power_wait) + if power_wait < 0: + raise ValueError + except (KeyError, AttributeError), e: + power_wait = None + except Exception, e: + power_wait = None + errors.append('An invalid value for power_wait was given: "%s"' % form['power_wait']) + if power_wait: + fencedev.addAttribute('power_wait', str(power_wait)) + else: + fencedev.removeAttribute('power_wait') + + try: + udpport = form['udpport'].strip() + if udpport: + udpport = int(udpport) + if udpport < 1 or udpport & 0xffff != udpport: + raise ValueError + except (KeyError, AttributeError), e: + udpport = None + except Exception, e: + udpport = None + errors.append('An invalid value for udpport was given: "%s"' % form['udpport']) + if udpport: + fencedev.addAttribute('udpport', str(udpport)) + else: + fencedev.removeAttribute('udpport') + + try: + snmp_community = form['community'].strip() + except Exception, e: + snmp_community = None + if snmp_community: + fencedev.addAttribute('community', snmp_community) + else: + fencedev.removeAttribute('community') + + has_passwd = False + try: + pwd = form['passwd'].strip() + if not pwd: + # Allow passwords that consist of only spaces. + if not form.has_key('passwd') or form['passwd'] == '': + raise Exception, 'blank' + else: + pwd = form['passwd'] + fencedev.addAttribute('passwd', pwd) + has_passwd = True + except Exception, e: + try: + fencedev.removeAttribute('passwd') + except: + pass + + try: + pwd_script = form['passwd_script'].strip() + if not pwd_script: + raise Exception, 'blank' + fencedev.addAttribute('passwd_script', pwd_script) + has_passwd = True + except Exception, e: + try: + fencedev.removeAttribute('passwd_script') + except: + pass + + if not has_passwd: + errors.append(FD_PROVIDE_PASSWD) + + try: + pwd = form['snmp_priv_passwd'].strip() + if not pwd: + # Allow passwords that consist of only spaces. + if not form.has_key('snmp_priv_passwd') or form['snmp_priv_passwd'] == '': + raise Exception, 'blank' + else: + pwd = form['snmp_priv_passwd'] + fencedev.addAttribute('snmp_priv_passwd', pwd) + has_passwd = True + except Exception, e: + try: + fencedev.removeAttribute('snmp_priv_passwd') + except: + pass + + try: + pwd_script = form['snmp_priv_passwd_script'].strip() + if not pwd_script: + raise Exception, 'blank' + fencedev.addAttribute('snmp_priv_passwd_script', pwd_script) + has_passwd = True + except Exception, e: + try: + fencedev.removeAttribute('snmp_priv_passwd_script') + except: + pass + + try: + snmp_version = form['snmp_version'].strip() + if not snmp_version in ('1', '2c', '3'): + snmp_version = None + raise Exception, 'blank' + fencedev.addAttribute('snmp_version', snmp_version) + except Exception, e: + try: + fencedev.removeAttribute('snmp_version') + except: + pass + + try: + snmp_sec_level = form['snmp_sec_level'].strip() + if not snmp_sec_level in ('noAuthNoPriv', 'authNoPriv', 'authPriv'): + snmp_sec_level = None + raise Exception, 'blank' + fencedev.addAttribute('snmp_sec_level', snmp_sec_level) + except Exception, e: + try: + fencedev.removeAttribute('snmp_sec_level') + except: + pass + + try: + snmp_auth_prot = form['snmp_auth_prot'].strip() + if not snmp_auth_prot in ('MD5', 'SHA'): + snmp_auth_prot = None + raise Exception, 'blank' + fencedev.addAttribute('snmp_auth_prot', snmp_auth_prot) + except Exception, e: + try: + fencedev.removeAttribute('snmp_auth_prot') + except: + pass + + try: + snmp_priv_prot = form['snmp_priv_prot'].strip() + if not snmp_priv_prot in ('DES', 'AES'): + snmp_priv_prot = None + raise Exception, 'blank' + fencedev.addAttribute('snmp_priv_prot', snmp_priv_prot) + except Exception, e: + try: + fencedev.removeAttribute('snmp_priv_prot') + except: + pass + + return errors + def val_noop_fd(dummy, _dummy): return [] @@ -1115,6 +1285,7 @@ 'fence_egenera': val_egenera_fd, 'fence_bullpap': val_bullpap_fd, 'fence_lpar': val_lpar_fd, + 'fence_cisco_mds': val_cisco_mds_fd, 'fence_vmware': val_vmware_fd, 'fence_xvm': val_noop_fd, 'fence_scsi': val_noop_fd, @@ -1417,6 +1588,19 @@ return errors +def val_cisco_mds_fi(form, fenceinst): + errors = list() + + try: + port = form['port'].strip() + if not port: + raise Exception, 'blank' + fenceinst.addAttribute('port', port) + except Exception, e: + errors.append(FI_PROVIDE_PORT) + + return errors + def val_manual_fi(form, fenceinst): nodename = form.get('nodename') if nodename: @@ -1441,6 +1625,7 @@ 'fence_xvm': val_xvm_fi, 'fence_scsi': val_scsi_fi, 'fence_lpar': val_lpar_fi, + 'fence_cisco_mds': val_cisco_mds_fi, 'fence_vmware': val_vmware_fi, 'fence_ilo': val_noop_fi, 'fence_ipmilan': val_noop_fi, Index: luci/site/luci/Extensions/ClusterModel/FenceDeviceAttr.py =================================================================== RCS file: /cvs/cluster/conga/luci/site/luci/Extensions/ClusterModel/FenceDeviceAttr.py,v retrieving revision 1.5.2.4 diff -u -r1.5.2.4 FenceDeviceAttr.py --- a/luci/site/luci/Extensions/ClusterModel/FenceDeviceAttr.py 5 Aug 2010 17:33:05 -0000 1.5.2.4 +++ b/luci/site/luci/Extensions/ClusterModel/FenceDeviceAttr.py 31 Aug 2010 20:01:39 -0000 @@ -31,6 +31,7 @@ 'fence_rps10': 'RPS10 Serial Switch', 'fence_lpar': 'LPAR Fencing', 'fence_vmware': 'VMware Fencing', + 'fence_cisco_mds': 'Cisco MDS', 'fence_manual': 'Manual Fencing' } @@ -49,6 +50,7 @@ 'fence_scsi': True, 'fence_lpar': True, 'fence_vmware': True, + 'fence_cisco_mds': True, 'fence_ilo': False, 'fence_ipmilan': False, 'fence_drac': False, @@ -92,6 +94,7 @@ 'fence_scsi': ( 'node' ), 'fence_lpar': ( 'partition' ), 'fence_vmware': ( 'port' ), + 'fence_cisco_mds': ( 'port' ), 'fence_ilo': ( ), 'fence_ipmilan': ( ), 'fence_drac': ( ), @@ -127,6 +130,8 @@ ( 'name', 'ipaddr', 'login', 'passwd' ), 'fence_vmware': ( 'name', 'ipaddr', 'login', 'passwd', 'vmlogin', 'vmpasswd' ), + 'fence_cisco_mds': + ( 'name', 'ipaddr', 'login', 'passwd' ), 'fence_scsi': ( 'name' ), 'fence_ilo':