Merge branch 'develop' into develop

This commit is contained in:
FraaJad 2018-07-23 14:18:06 -07:00 committed by GitHub
commit 093dfad578
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 438 additions and 215 deletions

View File

@ -152,18 +152,18 @@ command:
CloudStack specific settings
============================
security_group
securitygroup
~~~~~~~~~~~~~~
.. versionadded:: next-release
.. versionadded:: 2017.7.0
You can specify a list of security groups (by name or id) that should be
assigned to the VM.
assigned to the VM:
.. code-block:: yaml
exoscale:
provider: cloudstack
security_group:
securitygroup:
- default
- salt-master

View File

@ -236,6 +236,9 @@ Server configuration values and their defaults:
# Use TLS when connecting
auth.ldap.tls: False
# Use STARTTLS when connecting
auth.ldap.starttls: False
# LDAP scope level, almost always 2
auth.ldap.scope: 2

View File

@ -191,44 +191,21 @@ If (!($Path.ToLower().Contains("$($ini['Settings']['Scripts2Dir'])".ToLower())))
#==============================================================================
# Update PIP and SetupTools
# caching depends on environment variable SALT_PIP_LOCAL_CACHE
#==============================================================================
Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Updating PIP and SetupTools . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_PIP_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
} else {
$p = New-Item $Env:SALT_PIP_LOCAL_CACHE -ItemType Directory -Force # Ensure directory exists
if ( (Get-ChildItem $Env:SALT_PIP_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req_pip.txt into empty local cache SALT_REQ_PIP $Env:SALT_PIP_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_PIP_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
}
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
#==============================================================================
# Install pypi resources using pip
# caching depends on environment variable SALT_REQ_LOCAL_CACHE
#==============================================================================
Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Installing pypi resources using pip . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_REQ_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req.txt" "pip install"
} else {
if ( (Get-ChildItem $Env:SALT_REQ_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req.txt into empty local cache SALT_REQ $Env:SALT_REQ_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_REQ_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
}
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python2Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req.txt" "pip install"
#==============================================================================
# Cleaning Up PyWin32
@ -295,9 +272,7 @@ If (-Not $Silent) {
# Remove the temporary download directory
#------------------------------------------------------------------------------
Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Cleaning up downloaded files unless you use SALTREPO_LOCAL_CACHE"
Write-Output " - $script_name :: Cleaning up downloaded files"
Write-Output " ----------------------------------------------------------------"
Write-Output ""
if ( ! [bool]$Env:SALTREPO_LOCAL_CACHE ) {
Remove-Item $($ini['Settings']['DownloadDir']) -Force -Recurse
}
Remove-Item $($ini['Settings']['DownloadDir']) -Force -Recurse

View File

@ -191,44 +191,19 @@ If (!($Path.ToLower().Contains("$($ini['Settings']['Scripts3Dir'])".ToLower())))
#==============================================================================
# Update PIP and SetupTools
# caching depends on environment variable SALT_PIP_LOCAL_CACHE
#==============================================================================
Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Updating PIP and SetupTools . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_PIP_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
} else {
$p = New-Item $Env:SALT_PIP_LOCAL_CACHE -ItemType Directory -Force # Ensure directory exists
if ( (Get-ChildItem $Env:SALT_PIP_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req_pip.txt into empty local cache SALT_REQ_PIP $Env:SALT_PIP_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_PIP_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_PIP_LOCAL_CACHE -r $($script_path)\req_pip.txt" "pip install"
}
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req_pip.txt" "python pip"
#==============================================================================
# Install pypi resources using pip
# caching depends on environment variable SALT_REQ_LOCAL_CACHE
#==============================================================================
Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Installing pypi resources using pip . . ."
Write-Output " ----------------------------------------------------------------"
if ( ! [bool]$Env:SALT_REQ_LOCAL_CACHE) {
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req.txt" "pip install"
} else {
if ( (Get-ChildItem $Env:SALT_REQ_LOCAL_CACHE | Measure-Object).Count -eq 0 ) {
# folder empty
Write-Output " pip download from req.txt into empty local cache SALT_REQ $Env:SALT_REQ_LOCAL_CACHE"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check download --dest $Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip download"
}
Write-Output " reading from local pip cache $Env:SALT_REQ_LOCAL_CACHE"
Write-Output " If a (new) resource is missing, please delete all files in this cache, go online and repeat"
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check install --no-index --find-links=$Env:SALT_REQ_LOCAL_CACHE -r $($script_path)\req.txt" "pip install"
}
Start_Process_and_test_exitcode "cmd" "/c $($ini['Settings']['Python3Dir'])\python.exe -m pip --disable-pip-version-check --no-cache-dir install -r $($script_path)\req.txt" "pip install"
#==============================================================================
# Cleaning Up PyWin32
@ -304,9 +279,7 @@ If (-Not $Silent) {
# Remove the temporary download directory
#------------------------------------------------------------------------------
Write-Output " ----------------------------------------------------------------"
Write-Output " - $script_name :: Cleaning up downloaded files unless you use SALTREPO_LOCAL_CACHE"
Write-Output " - $script_name :: Cleaning up downloaded files"
Write-Output " ----------------------------------------------------------------"
Write-Output ""
if ( ! [bool]$Env:SALTREPO_LOCAL_CACHE ) {
Remove-Item $($ini['Settings']['DownloadDir']) -Force -Recurse
}
Remove-Item $($ini['Settings']['DownloadDir']) -Force -Recurse

View File

@ -1,5 +1,5 @@
#
# Download url to file. Optionally, store in cache
# ps1 wrapper for psm1
#
#
Param(
@ -7,33 +7,7 @@ Param(
[Parameter(Mandatory=$true)][string]$file
)
$VerbosePreference = 'Continue'
Import-Module ./Modules/download-module.psm1
if ( [bool]$Env:SALTREPO_LOCAL_CACHE) {
Write-Verbose "found SALTREPO_LOCAL_CACHE environment variable $Env:SALTREPO_LOCAL_CACHE"
} else {
Write-Verbose "no SALTREPO_LOCAL_CACHE environment variable "
}
$saltrepo_url = "http://repo.saltstack.com/windows/dependencies/"
if ( [bool]$Env:SALTREPO_LOCAL_CACHE -And $url.StartsWith($saltrepo_url) ) {
Write-Verbose "found SALTREPO_LOCAL_CACHE environment variable and url is saltrepo"
$url_relative__slash = $url -replace [regex]::Escape($saltrepo_url), ""
$url_relative__backslash = $url_relative__slash -replace [regex]::Escape("/"), "\\"
$localCacheFile = Join-Path $Env:SALTREPO_LOCAL_CACHE $url_relative__backslash
if (-Not (Test-Path $localCacheFile)) {
Write-Verbose "downloading to cache $localCacheFile"
DownloadFileWithProgress $url $localCacheFile
}
Write-Verbose "copying from cache $file"
Copy-Item $localCacheFile -destination $file
} else {
Write-Verbose "no SALTREPO_LOCAL_CACHE environment variable, or URL not saltrepo, downloading directly"
DownloadFileWithProgress $url $file
}
DownloadFileWithProgress $url $file

View File

@ -8,12 +8,6 @@ Function DownloadFileWithProgress {
# $url - the file source
# $localfile - the file destination on the local machine
# Originally, DownLoadDir is deleted for each install, therefore
# this function did not expect that the file exists.
# You may want to set an environment variable SALTREPO_LOCAL_CACHE, a cache which lives as long as you decide.
# Therefore this function must test if the file exists.
param(
[Parameter(Mandatory=$true)]
[String] $url,
@ -21,56 +15,46 @@ Function DownloadFileWithProgress {
[String] $localFile = (Join-Path $pwd.Path $url.SubString($url.LastIndexOf('/')))
)
begin {
$Global:NEED_PROCESS_AND_END = $true
Write-Verbose " **** DownloadFileWithProgress looking for **** $localFile ********"
if ( [bool]$Env:SALTREPO_LOCAL_CACHE -and (Test-Path $localFile) ) {
Write-Verbose " **** found **** $localFile ********"
$Global:NEED_PROCESS_AND_END = $false
} else {
Write-Verbose " ++++++ BEGIN DOWNLOADING ++++++ $localFile +++++++"
$client = New-Object System.Net.WebClient
$Global:downloadComplete = $false
$eventDataComplete = Register-ObjectEvent $client DownloadFileCompleted `
Write-Host -ForegroundColor DarkGreen " download-module.DownloadFileWithProgress $url"
$client = New-Object System.Net.WebClient
$Global:downloadComplete = $false
$eventDataComplete = Register-ObjectEvent $client DownloadFileCompleted `
-SourceIdentifier WebClient.DownloadFileComplete `
-Action {$Global:downloadComplete = $true}
$eventDataProgress = Register-ObjectEvent $client DownloadProgressChanged `
$eventDataProgress = Register-ObjectEvent $client DownloadProgressChanged `
-SourceIdentifier WebClient.DownloadProgressChanged `
-Action { $Global:DPCEventArgs = $EventArgs }
}
}
}
process {
if ( $Global:NEED_PROCESS_AND_END ) {
Write-Verbose " ++++++ actually DOWNLOADING ++++++ $localFile +++++++"
Write-Progress -Activity 'Downloading file' -Status $url
$client.DownloadFileAsync($url, $localFile)
Write-Progress -Activity 'Downloading file' -Status $url
$client.DownloadFileAsync($url, $localFile)
while (!($Global:downloadComplete)) {
$pc = $Global:DPCEventArgs.ProgressPercentage
if ($pc -ne $null) {
Write-Progress -Activity 'Downloading file' -Status $url -PercentComplete $pc
}
while (!($Global:downloadComplete)) {
$pc = $Global:DPCEventArgs.ProgressPercentage
if ($pc -ne $null) {
Write-Progress -Activity 'Downloading file' -Status $url -PercentComplete $pc
}
Write-Progress -Activity 'Downloading file' -Status $url -Complete
}
Write-Progress -Activity 'Downloading file' -Status $url -Complete
}
end {
if ( $Global:NEED_PROCESS_AND_END ) {
Unregister-Event -SourceIdentifier WebClient.DownloadProgressChanged
Unregister-Event -SourceIdentifier WebClient.DownloadFileComplete
$client.Dispose()
$Global:downloadComplete = $null
$Global:DPCEventArgs = $null
Remove-Variable client
Remove-Variable eventDataComplete
Remove-Variable eventDataProgress
[GC]::Collect()
# Errorchecking
If (!((Test-Path "$localfile") -and ((Get-Item "$localfile").length -gt 0kb))) {
Write-Error "download-module.psm1 exits in error, download is missing or has zero-length: $localfile"
exit 2
}
Unregister-Event -SourceIdentifier WebClient.DownloadProgressChanged
Unregister-Event -SourceIdentifier WebClient.DownloadFileComplete
$client.Dispose()
$Global:downloadComplete = $null
$Global:DPCEventArgs = $null
Remove-Variable client
Remove-Variable eventDataComplete
Remove-Variable eventDataProgress
[GC]::Collect()
# 2016-07-06 mkr Errorchecking added. nice-to-have: integration into the above code.
If (!((Test-Path "$localfile") -and ((Get-Item "$localfile").length -gt 0kb))) {
Write-Error "Exiting because download missing or zero-length: $localfile"
exit 2
}
}
}
}

View File

@ -24,11 +24,6 @@ Function Get-Settings {
"SitePkgs3Dir" = "C:\Python35\Lib\site-packages"
"DownloadDir" = "$env:Temp\DevSalt"
}
# The script deletes the DownLoadDir (above) for each install.
# You may want to set an environment variable SALTREPO_LOCAL_CACHE, a cache which lives as long as you decide.
if ( [bool]$Env:SALTREPO_LOCAL_CACHE ) {
$Settings.Set_Item("DownloadDir", "$Env:SALTREPO_LOCAL_CACHE")
}
$ini.Add("Settings", $Settings)
Write-Verbose "DownloadDir === $($ini['Settings']['DownloadDir']) ==="

View File

@ -32,6 +32,7 @@ __defopts__ = {'auth.ldap.basedn': '',
'auth.ldap.uri': '',
'auth.ldap.server': 'localhost',
'auth.ldap.port': '389',
'auth.ldap.starttls': False,
'auth.ldap.tls': False,
'auth.ldap.no_verify': False,
'auth.ldap.anonymous': False,
@ -82,7 +83,9 @@ class _LDAPConnection(object):
Setup an LDAP connection.
'''
def __init__(self, uri, server, port, tls, no_verify, binddn, bindpw,
def __init__(self, uri, server, port,
starttls, tls, no_verify,
binddn, bindpw,
anonymous, accountattributename, activedirectory=False):
'''
Bind to an LDAP directory using passed credentials.
@ -90,8 +93,8 @@ class _LDAPConnection(object):
self.uri = uri
self.server = server
self.port = port
self.starttls = starttls
self.tls = tls
schema = 'ldaps' if tls else 'ldap'
self.binddn = binddn
self.bindpw = bindpw
if not HAS_LDAP:
@ -99,6 +102,13 @@ class _LDAPConnection(object):
'LDAP connection could not be made, the python-ldap module is '
'not installed. Install python-ldap to use LDAP external auth.'
)
if self.starttls and self.tls:
raise CommandExecutionError(
'Cannot bind with both starttls and tls enabled.'
'Please enable only one of the protocols'
)
schema = 'ldaps' if tls else 'ldap'
if self.uri == '':
self.uri = '{0}://{1}:{2}'.format(schema, self.server, self.port)
@ -116,6 +126,8 @@ class _LDAPConnection(object):
raise CommandExecutionError(
'LDAP bind password is not set: password cannot be empty if auth.ldap.anonymous is False'
)
if self.starttls:
self.ldap.start_tls_s()
self.ldap.simple_bind_s(self.binddn, self.bindpw)
except Exception as ldap_error:
raise CommandExecutionError(
@ -136,7 +148,8 @@ def _bind_for_search(anonymous=False, opts=None):
connargs = {}
# config params (auth.ldap.*)
params = {
'mandatory': ['uri', 'server', 'port', 'tls', 'no_verify', 'anonymous',
'mandatory': ['uri', 'server', 'port', 'starttls', 'tls',
'no_verify', 'anonymous',
'accountattributename', 'activedirectory'],
'additional': ['binddn', 'bindpw', 'filter', 'groupclass',
'auth_by_group_membership_only'],
@ -180,7 +193,8 @@ def _bind(username, password, anonymous=False, opts=None):
connargs = {}
# config params (auth.ldap.*)
params = {
'mandatory': ['uri', 'server', 'port', 'tls', 'no_verify', 'anonymous',
'mandatory': ['uri', 'server', 'port', 'starttls', 'tls',
'no_verify', 'anonymous',
'accountattributename', 'activedirectory'],
'additional': ['binddn', 'bindpw', 'filter', 'groupclass',
'auth_by_group_membership_only'],

View File

@ -299,22 +299,19 @@ def compliance_report(filepath=None,
(including pure Python).
string
.. versionchanged:: Fluorine
.. versionadded:: Fluorine
The compliance report send as inline string, to be used as the file to
send through the renderer system. Note, not all renderer modules can
work with strings; the 'py' renderer requires a file, for example.
renderer: ``jinja|yaml``
.. versionchanged:: Fluorine
.. versionadded:: Fluorine
The renderer pipe to send the file through; this is overridden by a
"she-bang" at the top of the file.
kwargs
.. versionchanged:: Fluorine
Keyword args to pass to Salt's compile_template() function.
@ -413,6 +410,23 @@ def netmiko_args(**kwargs):
Return the key-value arguments used for the authentication arguments for
the netmiko module.
When running in a non-native NAPALM driver (e.g., ``panos``, `f5``, ``mos`` -
either from https://github.com/napalm-automation-community or defined in
user's own environment, one can specify the Netmiko device type (the
``device_type`` argument) via the ``netmiko_device_type_map`` configuration
option / Pillar key, e.g.,
.. code-block:: yaml
netmiko_device_type_map:
f5: f5_ltm
dellos10: dell_os10
The configuration above defines the mapping between the NAPALM ``os`` Grain
and the Netmiko ``device_type``, e.g., when the NAPALM Grain is ``f5``, it
would use the ``f5_ltm`` SSH Netmiko driver to execute commands over SSH on
the remote network device.
CLI Example:
.. code-block:: bash
@ -440,7 +454,10 @@ def netmiko_args(**kwargs):
'fortios': 'fortinet',
'panos': 'paloalto_panos',
'aos': 'alcatel_aos',
'vyos': 'vyos'
'vyos': 'vyos',
'f5': 'f5_ltm',
'ce': 'huawei',
's350': 'cisco_s300'
}
# If you have a device type that is not listed here, please submit a PR
# to add it, and/or add the map into your opts/Pillar: netmiko_device_type_map
@ -925,3 +942,347 @@ def junos_call(fun, *args, **kwargs):
'comment': '{} is not a valid function'.format(fun)
}
return __salt__[mod_fun](*args, **kwargs)
def pyeapi_nxos_api_args(**prev_kwargs):
'''
.. versionadded:: Fluorine
Return the key-value arguments used for the authentication arguments for the
:mod:`pyeapi execution module <salt.module.arista_pyeapi>`.
CLI Example:
.. code-block:: bash
salt '*' napalm.pyeapi_nxos_api_args
'''
kwargs = {}
napalm_opts = salt.utils.napalm.get_device_opts(__opts__, salt_obj=__salt__)
optional_args = napalm_opts['OPTIONAL_ARGS']
kwargs['host'] = napalm_opts['HOSTNAME']
kwargs['username'] = napalm_opts['USERNAME']
kwargs['password'] = napalm_opts['PASSWORD']
kwargs['timeout'] = napalm_opts['TIMEOUT']
kwargs['transport'] = optional_args.get('transport')
kwargs['port'] = optional_args.get('port')
kwargs['verify'] = optional_args.get('verify')
prev_kwargs.update(kwargs)
return prev_kwargs
@proxy_napalm_wrap
def pyeapi_run_commands(*commands, **kwargs):
'''
Execute a list of commands on the Arista switch, via the ``pyeapi`` library.
This function forwards the existing connection details to the
:mod:`pyeapi.run_commands <salt.module.arista_pyeapi.run_commands>`
execution function.
commands
A list of commands to execute.
encoding: ``json``
The requested encoding of the command output. Valid values for encoding
are ``json`` (default) or ``text``.
CLI Example:
.. code-block:: bash
salt '*' napalm.pyeapi_run_commands 'show version' encoding=text
salt '*' napalm.pyeapi_run_commands 'show ip bgp neighbors'
'''
pyeapi_kwargs = pyeapi_nxos_api_args(**kwargs)
return __salt__['pyeapi.run_commands'](*commands, **pyeapi_kwargs)
@proxy_napalm_wrap
def pyeapi_call(method, *args, **kwargs):
'''
.. versionadded:: Fluorine
Invoke an arbitrary method from the ``pyeapi`` library.
This function forwards the existing connection details to the
:mod:`pyeapi.run_commands <salt.module.arista_pyeapi.run_commands>`
execution function.
method
The name of the ``pyeapi`` method to invoke.
kwargs
Key-value arguments to send to the ``pyeapi`` method.
CLI Example:
.. code-block:: bash
salt '*' napalm.pyeapi_call run_commands 'show version' encoding=text
salt '*' napalm.pyeapi_call get_config as_string=True
'''
pyeapi_kwargs = pyeapi_nxos_api_args(**kwargs)
return __salt__['pyeapi.call'](method, *args, **pyeapi_kwargs)
@proxy_napalm_wrap
def pyeapi_conn(**kwargs):
'''
.. versionadded:: Fluorine
Return the connection object with the Arista switch, over ``pyeapi``,
passing the authentication details from the existing NAPALM connection.
.. warning::
This function is not suitable for CLI usage, more rather to be used in
various Salt modules, to reusing the established connection, as in
opposite to opening a new connection for each task.
Usage example:
.. code-block:: python
conn = __salt__['napalm.pyeapi_conn']()
res1 = conn.run_commands('show version')
res2 = conn.get_config(as_string=True)
'''
pyeapi_kwargs = pyeapi_nxos_api_args(**kwargs)
return __salt__['pyeapi.get_connection'](**pyeapi_kwargs)
@proxy_napalm_wrap
def pyeapi_config(commands=None,
config_file=None,
template_engine='jinja',
context=None,
defaults=None,
saltenv='base',
**kwargs):
'''
.. versionadded:: Fluorine
Configures the Arista switch with the specified commands, via the ``pyeapi``
library. This function forwards the existing connection details to the
:mod:`pyeapi.run_commands <salt.module.arista_pyeapi.run_commands>`
execution function.
commands
The list of configuration commands to load on the Arista switch.
.. note::
This argument is ignored when ``config_file`` is specified.
config_file
The source file with the configuration commands to be sent to the device.
The file can also be a template that can be rendered using the template
engine of choice. This can be specified using the absolute path to the
file, or using one of the following URL schemes:
- ``salt://``
- ``https://``
- ``ftp:/``
- ``s3:/``
- ``swift://``
template_engine: ``jinja``
The template engine to use when rendering the source file. Default:
``jinja``. To simply fetch the file without attempting to render, set
this argument to ``None``.
context: ``None``
Variables to add to the template context.
defaults: ``None``
Default values of the ``context`` dict.
saltenv: ``base``
Salt fileserver environment from which to retrieve the file. Ignored if
``config_file`` is not a ``salt://`` URL.
CLI Example:
.. code-block:: bash
salt '*' napalm.pyeapi_config 'ntp server 1.2.3.4'
'''
pyeapi_kwargs = pyeapi_nxos_api_args(**kwargs)
return __salt__['pyeapi.config'](commands=commands,
config_file=config_file,
template_engine=template_engine,
context=context,
defaults=defaults,
saltenv=saltenv,
**pyeapi_kwargs)
@proxy_napalm_wrap
def nxos_api_rpc(commands,
method='cli',
**kwargs):
'''
.. versionadded:: Fluorine
Execute an arbitrary RPC request via the Nexus API.
commands
The RPC commands to be executed.
method: ``cli``
The type of the response, i.e., raw text (``cli_ascii``) or structured
document (``cli``). Defaults to ``cli`` (structured data).
CLI Example:
.. code-block:: bash
salt '*' napalm.nxos_api_rpc 'show version'
'''
nxos_api_kwargs = pyeapi_nxos_api_args(**kwargs)
return __salt__['nxos_api.rpc'](commands, method=method, **nxos_api_kwargs)
@proxy_napalm_wrap
def nxos_api_config(commands=None,
config_file=None,
template_engine='jinja',
context=None,
defaults=None,
saltenv='base',
**kwargs):
'''
.. versionadded:: Fluorine
Configures the Nexus switch with the specified commands, via the NX-API.
commands
The list of configuration commands to load on the Nexus switch.
.. note::
This argument is ignored when ``config_file`` is specified.
config_file
The source file with the configuration commands to be sent to the device.
The file can also be a template that can be rendered using the template
engine of choice. This can be specified using the absolute path to the
file, or using one of the following URL schemes:
- ``salt://``
- ``https://``
- ``ftp:/``
- ``s3:/``
- ``swift://``
template_engine: ``jinja``
The template engine to use when rendering the source file. Default:
``jinja``. To simply fetch the file without attempting to render, set
this argument to ``None``.
context: ``None``
Variables to add to the template context.
defaults: ``None``
Default values of the ``context`` dict.
saltenv: ``base``
Salt fileserver environment from which to retrieve the file. Ignored if
``config_file`` is not a ``salt://`` URL.
CLI Example:
.. code-block:: bash
salt '*' napalm.nxos_api_config 'spanning-tree mode mstp'
salt '*' napalm.nxos_api_config config_file=https://bit.ly/2LGLcDy context="{'servers': ['1.2.3.4']}"
'''
nxos_api_kwargs = pyeapi_nxos_api_args(**kwargs)
return __salt__['nxos_api.config'](commands=commands,
config_file=config_file,
template_engine=template_engine,
context=context,
defaults=defaults,
saltenv=saltenv,
**nxos_api_kwargs)
@proxy_napalm_wrap
def nxos_api_show(commands, raw_text=True, **kwargs):
'''
.. versionadded:: Fluorine
Execute one or more show (non-configuration) commands.
commands
The commands to be executed.
raw_text: ``True``
Whether to return raw text or structured data.
CLI Example:
.. code-block:: bash
salt '*' napalm.nxos_api_show 'show version'
salt '*' napalm.nxos_api_show 'show bgp sessions' 'show processes' raw_text=False
'''
nxos_api_kwargs = pyeapi_nxos_api_args(**kwargs)
return __salt__['nxos_api.show'](commands,
raw_text=raw_text,
**nxos_api_kwargs)
@proxy_napalm_wrap
def rpc(command, **kwargs):
'''
.. versionadded:: Fluorine
This is a wrapper to execute RPC requests on various network operating
systems supported by NAPALM, invoking the following functions for the NAPALM
native drivers:
- :py:func:`napalm.junos_rpc <salt.modules.napalm.junos_rpc>` for ``junos``
- :py:func:`napalm.pyeapi_run_commands <salt.modules.napalm.pyeapi_run_commands>`
for ``eos``
- :py:func:`napalm.nxos_api_rpc <salt.modules.napalm.nxos_api_rpc>` for
``nxos``
- :py:func:`napalm.netmiko_commands <salt.modules.napalm.netmiko_commands>`
for ``ios``, ``iosxr``, and ``nxos_ssh``
command
The RPC command to execute. This depends on the nature of the operating
system.
kwargs
Key-value arguments to be sent to the underlying Execution function.
The function capabilities are extensible in the user environment via the
``napalm_rpc_map`` configuration option / Pillar, e.g.,
.. code-block:: yaml
napalm_rpc_map:
f5: napalm.netmiko_commands
panos: panos.call
The mapping above reads: when the NAPALM ``os`` Grain is ``f5``, then call
``napalm.netmiko_commands`` for RPC requests.
By default, if the user does not specify any map, non-native NAPALM drivers
will invoke the ``napalm.netmiko_commands`` Execution function.
CLI Example:
.. code-block:: bash
salt '*' napalm.rpc 'show version'
salt '*' napalm.rpc get-interfaces
'''
default_map = {
'junos': 'napalm.junos_rpc',
'eos': 'napalm.pyeapi_run_commands',
'nxos': 'napalm.nxos_api_rpc'
}
napalm_map = __salt__['config.get']('napalm_rpc_map', {})
napalm_map.update(default_map)
fun = napalm_map.get(__grains__['os'], 'napalm.netmiko_commands')
return __salt__[fun](command, **kwargs)

View File

@ -314,7 +314,7 @@ def version(*names, **kwargs):
ret[_ips_get_pkgname(line)] = _ips_get_pkgversion(line)
# Append package names which are not installed/found
unmatched = list([name for name in names if not reduce(lambda x, y: x or name in y, ret, False)])
unmatched = list([name for name in names if not reduce(lambda x, y: x or name in y, ret, False)]) # pylint: disable=W0640
ret.update(zip(unmatched, itertools.cycle(('',))))
# Return a string if only one package name passed

View File

@ -328,28 +328,6 @@ if WITH_SETUPTOOLS:
develop.run(self)
def uri_to_resource(resource_file):
# ## Returns the URI for a resource
# The basic case is that the resource is on saltstack.com
# It could be the case that the resource is cached.
salt_uri = 'https://repo.saltstack.com/windows/dependencies/' + resource_file
if os.getenv('SALTREPO_LOCAL_CACHE') is None:
# if environment variable not set, return the basic case
return salt_uri
if not os.path.isdir(os.getenv('SALTREPO_LOCAL_CACHE')):
# if environment variable is not a directory, return the basic case
return salt_uri
cached_resource = os.path.join(os.getenv('SALTREPO_LOCAL_CACHE'), resource_file)
cached_resource = cached_resource.replace('/', '\\')
if not os.path.isfile(cached_resource):
# if file does not exist, return the basic case
return salt_uri
if os.path.getsize(cached_resource) == 0:
# if file has zero size, return the basic case
return salt_uri
return cached_resource
class DownloadWindowsDlls(Command):
description = 'Download required DLL\'s for windows'

View File

@ -28,7 +28,7 @@ class VaultTestCase(ModuleCase, ShellCase):
'''
config = '{"backend": {"file": {"path": "/vault/file"}}, "default_lease_ttl": "168h", "max_lease_ttl": "720h"}'
self.run_state('docker_image.present', name='vault', tag='0.9.6')
ret = self.run_state(
self.run_state(
'docker_container.running',
name='vault',
image='vault:0.9.6',
@ -39,12 +39,12 @@ class VaultTestCase(ModuleCase, ShellCase):
},
cap_add='IPC_LOCK',
)
ret = self.run_function(
self.run_function(
'cmd.run',
cmd='vault login token=testsecret'.format(FILES),
cmd='vault login token=testsecret',
env={'VAULT_ADDR': 'http://127.0.0.1:8200'},
)
ret = self.run_function(
self.run_function(
'cmd.run',
cmd='vault policy write testpolicy {0}/vault.hcl'.format(FILES),
env={'VAULT_ADDR': 'http://127.0.0.1:8200'},

View File

@ -1597,40 +1597,6 @@ class FilemodLineTests(TestCase, LoaderModuleMockMixin):
expected = self._get_body(file_modified)
assert writelines_content[0] == expected, (writelines_content[0], expected)
@with_tempfile()
def test_line_insert_ensure_before_first_line(self, name):
'''
Test for file.line for insertion ensuring the line is before first line
:return:
'''
cfg_content = '#!/bin/bash'
file_content = os.linesep.join([
'/etc/init.d/someservice restart',
'exit 0'
])
file_modified = os.linesep.join([
cfg_content,
'/etc/init.d/someservice restart',
'exit 0'
])
isfile_mock = MagicMock(side_effect=lambda x: True if x == name else DEFAULT)
with patch('os.path.isfile', isfile_mock), \
patch('os.stat', MagicMock(return_value=DummyStat())), \
patch('salt.utils.files.fopen',
mock_open(read_data=file_content)), \
patch('salt.utils.atomicfile.atomic_open',
mock_open()) as atomic_open_mock:
filemod.line(name, content=cfg_content, before='/etc/init.d/someservice restart', mode='ensure')
handles = atomic_open_mock.filehandles[name]
# We should only have opened the file once
open_count = len(handles)
assert open_count == 1, open_count
# We should only have invoked .writelines() once...
writelines_content = handles[0].writelines_calls
writelines_count = len(writelines_content)
assert writelines_count == 1, writelines_count
@with_tempfile()
def test_line_insert_ensure_after(self, name):
'''