mirror of
https://github.com/valitydev/salt.git
synced 2024-11-07 17:09:03 +00:00
Merge branch 'develop' into develop
This commit is contained in:
commit
093dfad578
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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']) ==="
|
||||
|
@ -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'],
|
||||
|
@ -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)
|
@ -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
|
||||
|
22
setup.py
22
setup.py
@ -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'
|
||||
|
@ -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'},
|
||||
|
@ -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):
|
||||
'''
|
||||
|
Loading…
Reference in New Issue
Block a user