mirror of
https://github.com/saltstack/salt.git
synced 2025-04-17 10:10:20 +00:00
Merge pull request #27922 from cro/fx2
WIP States/Modules for managing Dell FX2 chassis via salt-proxy
This commit is contained in:
commit
1085eeab2b
11 changed files with 1822 additions and 0 deletions
|
@ -53,6 +53,7 @@ Full list of builtin execution modules
|
|||
cabal
|
||||
cassandra
|
||||
cassandra_cql
|
||||
chassis
|
||||
chef
|
||||
chocolatey
|
||||
cloud
|
||||
|
@ -87,6 +88,7 @@ Full list of builtin execution modules
|
|||
dockerng
|
||||
dpkg
|
||||
drac
|
||||
dracr
|
||||
drbd
|
||||
ebuild
|
||||
eix
|
||||
|
|
6
doc/ref/modules/all/salt.modules.chassis.rst
Normal file
6
doc/ref/modules/all/salt.modules.chassis.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
====================
|
||||
salt.modules.chassis
|
||||
====================
|
||||
|
||||
.. automodule:: salt.modules.chassis
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.dracr.rst
Normal file
6
doc/ref/modules/all/salt.modules.dracr.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
==================
|
||||
salt.modules.dracr
|
||||
==================
|
||||
|
||||
.. automodule:: salt.modules.dracr
|
||||
:members:
|
|
@ -10,5 +10,6 @@ Full list of builtin proxy modules
|
|||
:toctree:
|
||||
:template: autosummary.rst.tmpl
|
||||
|
||||
fx2
|
||||
junos
|
||||
rest_sample
|
||||
|
|
6
doc/ref/proxy/all/salt.proxy.fx2.rst
Normal file
6
doc/ref/proxy/all/salt.proxy.fx2.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
==============
|
||||
salt.proxy.fx2
|
||||
==============
|
||||
|
||||
.. automodule:: salt.proxy.fx2
|
||||
:members:
|
|
@ -50,6 +50,7 @@ Full list of builtin state modules
|
|||
cyg
|
||||
ddns
|
||||
debconfmod
|
||||
dellchassis
|
||||
disk
|
||||
dockerio
|
||||
dockerng
|
||||
|
|
6
doc/ref/states/all/salt.states.dellchassis.rst
Normal file
6
doc/ref/states/all/salt.states.dellchassis.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
=======================
|
||||
salt.states.dellchassis
|
||||
=======================
|
||||
|
||||
.. automodule:: salt.states.dellchassis
|
||||
:members:
|
44
salt/modules/chassis.py
Normal file
44
salt/modules/chassis.py
Normal file
|
@ -0,0 +1,44 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Glue execution module to link to the :doc:`fx2 proxymodule </ref/proxy/all/salt.proxy.fx2>`.
|
||||
|
||||
Depends: :doc:`iDRAC Remote execution module (salt.modules.dracr) </ref/modules/all/salt.modules.dracr>`
|
||||
|
||||
For documentation on commands that you can direct to a Dell chassis via proxy,
|
||||
look in the documentation for :doc:`salt.modules.dracr </ref/modules/all/salt.modules.dracr>`.
|
||||
|
||||
This execution module calls through to a function in the fx2 proxy module
|
||||
called ``chconfig``. That function looks up the function passed in the ``cmd``
|
||||
parameter in :doc:`salt.modules.dracr </ref/modules/all/salt.modules.dracr>` and calls it.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import python libs
|
||||
import logging
|
||||
import salt.utils
|
||||
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
__proxyenabled__ = ['fx2']
|
||||
__virtualname__ = 'chassis'
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only work on proxy
|
||||
'''
|
||||
if salt.utils.is_proxy():
|
||||
return __virtualname__
|
||||
return False
|
||||
|
||||
|
||||
def cmd(cmd, *args, **kwargs):
|
||||
proxycmd = __opts__['proxy']['proxytype'] + '.chconfig'
|
||||
kwargs['admin_username'] = __pillar__['proxy']['admin_username']
|
||||
kwargs['admin_password'] = __pillar__['proxy']['admin_password']
|
||||
kwargs['host'] = __pillar__['proxy']['host']
|
||||
return __proxy__[proxycmd](cmd, *args, **kwargs)
|
||||
|
1173
salt/modules/dracr.py
Normal file
1173
salt/modules/dracr.py
Normal file
File diff suppressed because it is too large
Load diff
252
salt/proxy/fx2.py
Normal file
252
salt/proxy/fx2.py
Normal file
|
@ -0,0 +1,252 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
======
|
||||
fx2.py
|
||||
======
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
Proxy minion interface module for managing Dell FX2 chassis (Dell
|
||||
Chassis Management Controller version 1.2 and above, iDRAC8 version 2.00
|
||||
and above)
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
- :doc:`iDRAC Remote execution module (salt.modules.dracr) </ref/modules/all/salt.modules.dracr>`
|
||||
- :doc:`Chassis command shim (salt.modules.chassis) </ref/modules/all/salt.modules.chassis>`
|
||||
- :doc:`Dell Chassis States (salt.states.dellchassis) </ref/states/all/salt.states.dellchassis>`
|
||||
- Dell's ``racadm`` command line interface to CMC and iDRAC devices.
|
||||
|
||||
|
||||
**Special Note: SaltStack thanks** `Adobe Corporation <http://adobe.com/>`_
|
||||
**for their support in creating this proxy minion integration.**
|
||||
|
||||
This proxy minion enables Dell FX2 and FX2s (hereafter referred to as
|
||||
simply "chassis", "CMC", or "FX2") chassis to be treated individually
|
||||
like a salt-minion.
|
||||
|
||||
Since the CMC embedded in the chassis does not run an OS capable of hosting a
|
||||
Python stack, the chassis can't run a minion directly. Salt's "Proxy Minion"
|
||||
functionality enables you to designate another machine to host a minion
|
||||
process that "proxies" communication from the salt-master. The master does not
|
||||
know nor care that the target is not a real minion.
|
||||
|
||||
More in-depth conceptual reading on Proxy Minions can be found
|
||||
:doc:`in the Proxy Minion section </topics/proxyminion/index>` of
|
||||
Salt's documentation.
|
||||
|
||||
To configure this integration, follow these steps:
|
||||
|
||||
Pillar
|
||||
------
|
||||
|
||||
Proxy minions get their configuration from Salt's Pillar. Every proxy must
|
||||
have a stanza in Pillar, and a reference in the Pillar topfile that matches
|
||||
the ID. At a minimum for communication with the chassis the pillar should
|
||||
look like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
proxy:
|
||||
host: <ip or dns name of chassis controller>
|
||||
admin_username: <iDRAC username for the CMC, usually 'root'>
|
||||
admin_password: <iDRAC password. Dell default is 'calvin'>
|
||||
proxytype: fx2
|
||||
|
||||
The ``proxytype`` line above is critical, it tells Salt which interface to load
|
||||
from the ``proxy`` directory in Salt's install hierarchy, or from ``/srv/salt/_proxy``
|
||||
on the salt-master (if you have created your own proxy module, for example).
|
||||
|
||||
salt-proxy
|
||||
----------
|
||||
|
||||
After your pillar is in place, you can test the proxy. The proxy can run on
|
||||
any machine that has network connectivity to your salt-master and to the chassis in question.
|
||||
SaltStack recommends that this machine also run a regular minion, though
|
||||
it is not strictly necessary.
|
||||
|
||||
On the machine that will run the proxy, make sure there is an ``/etc/salt/proxy``
|
||||
file with at least the following in it:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
master: <ip or hostname of salt-master>
|
||||
|
||||
You can start the proxy with
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-proxy --proxyid <id you want to give the chassis>
|
||||
|
||||
You may want to add ``-l debug`` to run the above in the foreground in debug
|
||||
mode just to make sure everything is OK.
|
||||
|
||||
Next, accept the key for the proxy on your salt-master, just like you would
|
||||
for a regular minion:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-key -a <id you want to give the chassis>
|
||||
|
||||
You can confirm that the pillar data is in place for the proxy:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt <id> pillar.items
|
||||
|
||||
And now you should be able to ping the chassis to make sure it is responding:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt <id> test.ping
|
||||
|
||||
At this point you can execute one-off commands against the chassis. For
|
||||
example, you can get the chassis inventory:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt <id> chassis.cmd inventory
|
||||
|
||||
Note that you don't need to provide credentials or an ip/hostname. Salt knows
|
||||
to use the credentials you stored in Pillar.
|
||||
|
||||
It's important to understand how this particular proxy works.
|
||||
:doc:`Salt.modules.dracr </ref/modules/all/salt.modules.dracr>` is a standard Salt execution
|
||||
module. If you pull up the docs for it you'll see that almost every function
|
||||
in the module takes credentials and a target host. When credentials and a host
|
||||
aren't passed, Salt runs ``racadm`` against the local machine. If you wanted
|
||||
you could run functions from this module on any host where an appropriate
|
||||
version of ``racadm`` is installed, and that host would reach out over the network
|
||||
and communicate with the chassis.
|
||||
|
||||
``Chassis.cmd`` acts as a "shim" between the execution module and the proxy. It's
|
||||
first parameter is always the function from salt.modules.dracr to execute. If the
|
||||
function takes more positional or keyword arguments you can append them to the call.
|
||||
It's this shim that speaks to the chassis through the proxy, arranging for the
|
||||
credentials and hostname to be pulled from the pillar section for this proxy minion.
|
||||
|
||||
Because of the presence of the shim, to lookup documentation for what
|
||||
functions you can use to interface with the chassis, you'll want to
|
||||
look in :doc:`salt.modules.dracr </ref/modules/all/salt.modules.dracr>` instead
|
||||
of :doc:`salt.modules.chassis </ref/modules/all/salt.modules.chassis>`.
|
||||
|
||||
States
|
||||
------
|
||||
|
||||
Associated states are thoroughly documented in :doc:`salt.states.dellchassis </ref/states/all/salt.states.dellchassis>`.
|
||||
Look there to find an example structure for pillar as well as an example
|
||||
``.sls`` file for standing up a Dell Chassis from scratch.
|
||||
|
||||
'''
|
||||
from __future__ import absolute_import
|
||||
|
||||
# Import python libs
|
||||
import logging
|
||||
import salt.utils
|
||||
import salt.utils.http
|
||||
|
||||
# This must be present or the Salt loader won't load this module
|
||||
__proxyenabled__ = ['fx2']
|
||||
|
||||
|
||||
# Variables are scoped to this module so we can have persistent data
|
||||
# across calls to fns in here.
|
||||
GRAINS_CACHE = {}
|
||||
DETAILS = {}
|
||||
|
||||
# Want logging!
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
|
||||
def __virtual__():
|
||||
'''
|
||||
Only return if all the modules are available
|
||||
'''
|
||||
if not salt.utils.which('racadm'):
|
||||
log.critical('fx2 proxy minion needs "racadm" to be installed.')
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def init(opts):
|
||||
'''
|
||||
This function gets called when the proxy starts up. For
|
||||
FX2 devices we just cache the credentials and hostname.
|
||||
'''
|
||||
# Save the login details
|
||||
DETAILS['admin_username'] = opts['proxy']['admin_username']
|
||||
DETAILS['admin_password'] = opts['proxy']['admin_password']
|
||||
DETAILS['host'] = opts['proxy']['host']
|
||||
|
||||
|
||||
def grains():
|
||||
'''
|
||||
Get the grains from the proxied device
|
||||
'''
|
||||
if not GRAINS_CACHE:
|
||||
r = __salt__['dracr.system_info'](host=DETAILS['host'],
|
||||
admin_username=DETAILS['admin_username'],
|
||||
admin_password=DETAILS['admin_password'])
|
||||
GRAINS_CACHE = r
|
||||
return GRAINS_CACHE
|
||||
|
||||
|
||||
def grains_refresh():
|
||||
'''
|
||||
Refresh the grains from the proxied device
|
||||
'''
|
||||
GRAINS_CACHE = {}
|
||||
return grains()
|
||||
|
||||
|
||||
def chconfig(cmd, *args, **kwargs):
|
||||
'''
|
||||
This function is called by the :doc:`salt.modules.chassis.cmd </ref/modules/all/salt.modules.chassis>`
|
||||
shim. It then calls whatever is passed in ``cmd``
|
||||
inside the :doc:`salt.modules.dracr </ref/modules/all/salt.modules.dracr>`
|
||||
module.
|
||||
|
||||
:param cmd: The command to call inside salt.modules.dracr
|
||||
:param args: Arguments that need to be passed to that command
|
||||
:param kwargs: Keyword arguments that need to be passed to that command
|
||||
:return: Passthrough the return from the dracr module.
|
||||
|
||||
'''
|
||||
# Strip the __pub_ keys...is there a better way to do this?
|
||||
for k in kwargs.keys():
|
||||
if k.startswith('__pub_'):
|
||||
kwargs.pop(k)
|
||||
if 'dracr.'+cmd not in __salt__:
|
||||
return {'retcode': -1, 'message': 'dracr.' + cmd + ' is not available'}
|
||||
else:
|
||||
return __salt__['dracr.'+cmd](*args, **kwargs)
|
||||
|
||||
|
||||
def ping():
|
||||
'''
|
||||
Is the chassis responding?
|
||||
|
||||
:return: Returns False if the chassis didn't respond, True otherwise.
|
||||
|
||||
'''
|
||||
r = __salt__['dracr.system_info'](host=DETAILS['host'],
|
||||
admin_username=DETAILS['admin_username'],
|
||||
admin_password=DETAILS['admin_password'])
|
||||
if r.get('retcode', 0) == 1:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
try:
|
||||
return r['dict'].get('ret', False)
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
|
||||
def shutdown(opts):
|
||||
'''
|
||||
Shutdown the connection to the proxied device.
|
||||
For this proxy shutdown is a no-op.
|
||||
'''
|
||||
log.debug('fx2 proxy shutdown() called...')
|
325
salt/states/dellchassis.py
Normal file
325
salt/states/dellchassis.py
Normal file
|
@ -0,0 +1,325 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Manage chassis via Salt Proxies.
|
||||
|
||||
.. versionadded:: 2015.8.2
|
||||
|
||||
Example managing a Dell chassis:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
my-dell-chassis:
|
||||
chassis.dell:
|
||||
- name: my-dell-chassis
|
||||
- location: my-location
|
||||
- mode: 2
|
||||
- idrac_launch: 1
|
||||
- slot_names:
|
||||
- 1: my-slot-name
|
||||
- 2: my-other-slot-name
|
||||
- blade_power_states:
|
||||
- server-1: on
|
||||
- server-2: off
|
||||
- server-3: powercycle
|
||||
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def __virtual__():
|
||||
return 'chassis.cmd' in __salt__
|
||||
|
||||
|
||||
def blade_idrac(name, idrac_password=None, idrac_ipmi=None,
|
||||
idrac_ip=None, idrac_netmask=None, idrac_gateway=None,
|
||||
drac_dhcp=None):
|
||||
'''
|
||||
Set parameters for iDRAC in a blade.
|
||||
|
||||
:param name: The name of the blade to address
|
||||
:param idrac_password: Password to establish for the iDRAC interface
|
||||
:param idrac_ipmi: Enable/Disable IPMI over LAN
|
||||
:param idrac_ip: Set IP address for iDRAC
|
||||
:param idrac_netmask: Set netmask for iDRAC
|
||||
:param idrac_gateway: Set gateway for iDRAC
|
||||
:param drac_dhcp: Turn on DHCP for iDRAC (True turns on, False does nothing
|
||||
becaause setting a static IP will disable DHCP).
|
||||
:return: A standard Salt changes dictionary
|
||||
'''
|
||||
|
||||
pass
|
||||
|
||||
|
||||
def chassis(name, location=None, mode=None, idrac_launch=None, slot_names=None,
|
||||
blade_power_states=None):
|
||||
'''
|
||||
Manage a Dell Chassis.
|
||||
|
||||
name
|
||||
The name of the chassis.
|
||||
|
||||
location
|
||||
The location of the chassis.
|
||||
|
||||
mode
|
||||
The management mode of the chassis. Viable options are:
|
||||
|
||||
- 0: None
|
||||
- 1: Monitor
|
||||
- 2: Manage and Monitor
|
||||
|
||||
idrac_launch
|
||||
The iDRAC launch method of the chassis. Viable options are:
|
||||
|
||||
- 0: Disabled (launch iDRAC using IP address)
|
||||
- 1: Enabled (launch iDRAC using DNS name)
|
||||
|
||||
slot_names
|
||||
The names of the slots, provided as a list identified by
|
||||
their slot numbers.
|
||||
|
||||
blade_power_states
|
||||
The power states of a blade server, provided as a list and
|
||||
identified by their server numbers. Viable options are:
|
||||
|
||||
- on: Ensure the blade server is powered on.
|
||||
- off: Ensure the blade server is powered off.
|
||||
- powercycle: Power cycle the blade server.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
my-dell-chassis:
|
||||
chassis.dell:
|
||||
- name: my-dell-chassis
|
||||
- location: my-location
|
||||
- mode: 2
|
||||
- idrac_launch: 1
|
||||
- slot_names:
|
||||
- 1: my-slot-name
|
||||
- 2: my-other-slot-name
|
||||
- blade_power_states:
|
||||
- server-1: on
|
||||
- server-2: off
|
||||
- server-3: powercycle
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'changes': {},
|
||||
'comment': ''}
|
||||
|
||||
chassis_cmd = 'chassis.cmd'
|
||||
cfg_tuning = 'cfgRacTuning'
|
||||
mode_cmd = 'cfgRacTuneChassisMgmtAtServer'
|
||||
launch_cmd = 'cfgRacTuneIdracDNSLaunchEnable'
|
||||
|
||||
current_name = __salt__[chassis_cmd]('get_chassis_name')
|
||||
if name != current_name:
|
||||
ret['changes'].update({'Name':
|
||||
{'Old': current_name,
|
||||
'New': name}})
|
||||
|
||||
if location:
|
||||
current_location = __salt__[chassis_cmd]('get_chassis_location')
|
||||
if location != current_location:
|
||||
ret['changes'].update({'Location':
|
||||
{'Old': current_location,
|
||||
'New': location}})
|
||||
if mode:
|
||||
current_mode = __salt__[chassis_cmd]('get_general', cfg_tuning, mode_cmd)
|
||||
if mode != current_mode:
|
||||
ret['changes'].update({'Management Mode':
|
||||
{'Old': current_mode,
|
||||
'New': mode}})
|
||||
|
||||
if idrac_launch:
|
||||
current_launch_method = __salt__[chassis_cmd]('get_general', cfg_tuning, launch_cmd)
|
||||
if idrac_launch != current_launch_method:
|
||||
ret['changes'].update({'iDrac Launch Method':
|
||||
{'Old': current_launch_method,
|
||||
'New': idrac_launch}})
|
||||
|
||||
if slot_names:
|
||||
current_slot_names = __salt__[chassis_cmd]('list_slotnames')
|
||||
for key, val in slot_names:
|
||||
current_slot_name = current_slot_names.get(key).get('slotname')
|
||||
if current_slot_name != val['name']:
|
||||
old = {key: current_slot_name}
|
||||
new = {key: val}
|
||||
if ret['changes'].get('Slot Names') is None:
|
||||
ret['changes'].update({'Slot Names':
|
||||
{'Old': {},
|
||||
'New': {}}})
|
||||
ret['changes']['Slot Names']['Old'].update(old)
|
||||
ret['changes']['Slot Names']['New'].update(new)
|
||||
|
||||
# TODO: Refactor this and make DRY - can probable farm this out to a new funciton
|
||||
if blade_power_states:
|
||||
# TODO: Get the power state list working
|
||||
current_power_states = 'get a list of current power states'
|
||||
for key, val in blade_power_states:
|
||||
# TODO: Get the correct state infos
|
||||
current_power_state = current_power_states.get(key).get('state')
|
||||
# TODO: Don't just compare values, check if True should be "on" or "off" etc
|
||||
if current_power_state != val:
|
||||
old = {key: current_power_state}
|
||||
new = {key: val}
|
||||
if ret['changes'].get('Blade Power States') is None:
|
||||
ret['changes'].update({'Blade Power States':
|
||||
{'Old': {},
|
||||
'New': {}}})
|
||||
ret['changes']['Blade Power States']['Old'].update(old)
|
||||
ret['changes']['Blade Power States']['New'].update(new)
|
||||
|
||||
if ret['changes'] == {}:
|
||||
ret['comment'] = 'Dell chassis is already in the desired state.'
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Dell chassis configuration will change.'
|
||||
return ret
|
||||
|
||||
# Finally, set the necessary configurations on the chassis.
|
||||
name = __salt__[chassis_cmd]('set_chassis_name', name)
|
||||
if location:
|
||||
location = __salt__[chassis_cmd]('set_chassis_location', location)
|
||||
if mode:
|
||||
mode = __salt__[chassis_cmd]('set_general', cfg_tuning, mode_cmd, mode)
|
||||
if idrac_launch:
|
||||
idrac_launch = __salt__[chassis_cmd]('set_general', cfg_tuning, launch_cmd, idrac_launch)
|
||||
if slot_names:
|
||||
slot_rets = []
|
||||
for key, val in slot_names.iteritems():
|
||||
slot_name = val.get('slotname')
|
||||
slot_rets.append(__salt__[chassis_cmd]('set_slotname', key, slot_name))
|
||||
if any(slot_rets) is False:
|
||||
slot_names = False
|
||||
else:
|
||||
slot_names = True
|
||||
|
||||
if any([name, location, mode, idrac_launch, slot_names]) is False:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'There was an error setting the Dell chassis.'
|
||||
|
||||
ret['comment'] = 'Dell chassis was updated.'
|
||||
return ret
|
||||
|
||||
|
||||
def dell_switch(name, ip=None, netmask=None, gateway=None, dhcp=None,
|
||||
password=None, snmp=None):
|
||||
'''
|
||||
Manage switches in a Dell Chassis.
|
||||
|
||||
name
|
||||
The switch designation (e.g. switch-1, switch-2)
|
||||
|
||||
ip
|
||||
The Static IP Address of the switch
|
||||
|
||||
netmask
|
||||
The netmask for the static IP
|
||||
|
||||
gateway
|
||||
The gateway for the static IP
|
||||
|
||||
dhcp
|
||||
True: Enable DHCP
|
||||
False: Do not change DHCP setup
|
||||
(disabling DHCP is automatic when a static IP is set)
|
||||
|
||||
password
|
||||
The access (root) password for the switch
|
||||
|
||||
snmp
|
||||
The SNMP community string for the switch
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
my-dell-chassis:
|
||||
chassis.dell_switch:
|
||||
- switch: switch-1
|
||||
- ip: 192.168.1.1
|
||||
- netmask: 255.255.255.0
|
||||
- gateway: 192.168.1.254
|
||||
- dhcp: True
|
||||
- password: secret
|
||||
- snmp: public
|
||||
|
||||
'''
|
||||
ret = {'name': name,
|
||||
'result': True,
|
||||
'changes': {},
|
||||
'comment': ''}
|
||||
|
||||
current_nic = __salt__['chassis.cmd']('network_info', module=name)
|
||||
if current_nic.get('retcode', 0) != 0:
|
||||
ret['result'] = False
|
||||
ret['comment'] = current_nic['stdout']
|
||||
return ret
|
||||
|
||||
if ip or netmask or gateway:
|
||||
if not ip:
|
||||
ip = current_nic['Network']['IP Address']
|
||||
if not netmask:
|
||||
ip = current_nic['Network']['Subnet Mask']
|
||||
if not gateway:
|
||||
ip = current_nic['Network']['Gateway']
|
||||
|
||||
if current_nic['Network']['DHCP Enabled'] == '0' and dhcp:
|
||||
ret['changes'].update({'DHCP': {'Old': {'DHCP Enabled': current_nic['Network']['DHCP Enabled']},
|
||||
'New': {'DHCP Enabled': dhcp}}})
|
||||
|
||||
if ((ip or netmask or gateway) and not dhcp and (ip != current_nic['Network']['IP Address'] or
|
||||
netmask != current_nic['Network']['Subnet Mask'] or
|
||||
gateway != current_nic['Network']['Gateway'])):
|
||||
ret['changes'].update({'IP': {'Old': current_nic['Network'],
|
||||
'New': {'IP Address': ip,
|
||||
'Subnet Mask': netmask,
|
||||
'Gateway': gateway}}})
|
||||
|
||||
if password:
|
||||
if 'New' not in ret['changes']:
|
||||
ret['changes']['New'] = {}
|
||||
ret['changes']['New'].update({'Password': '*****'})
|
||||
|
||||
if snmp:
|
||||
if 'New' not in ret['changes']:
|
||||
ret['changes']['New'] = {}
|
||||
ret['changes']['New'].update({'SNMP': '*****'})
|
||||
|
||||
if ret['changes'] == {}:
|
||||
ret['comment'] = 'Switch ' + name + ' is already in desired state'
|
||||
return ret
|
||||
|
||||
if __opts__['test']:
|
||||
ret['result'] = None
|
||||
ret['comment'] = 'Switch ' + name + ' configuration will change'
|
||||
return ret
|
||||
|
||||
# Finally, set the necessary configurations on the chassis.
|
||||
dhcp_ret = net_ret = password_ret = snmp_ret = True
|
||||
if dhcp:
|
||||
dhcp_ret = __salt__['chassis.cmd']('set_niccfg', module=name, dhcp=dhcp)
|
||||
if ip or netmask or gateway:
|
||||
net_ret = __salt__['chassis.cmd']('set_niccfg', ip, netmask, gateway, module=name)
|
||||
if password:
|
||||
password_ret = __salt__['chassis.cmd']('deploy_password', 'root', password, module=name)
|
||||
|
||||
if snmp:
|
||||
snmp_ret = __salt__['chassis.cmd']('deploy_snmp', password, module=name)
|
||||
|
||||
if any([password_ret, snmp_ret, net_ret, dhcp_ret]) is False:
|
||||
ret['result'] = False
|
||||
ret['comment'] = 'There was an error setting the switch {0}.'.format(name)
|
||||
|
||||
ret['comment'] = 'Dell chassis switch {0} was updated.'.format(name)
|
||||
return ret
|
Loading…
Add table
Reference in a new issue