mirror of
https://github.com/saltstack/salt.git
synced 2025-04-16 09:40:20 +00:00
Merge branch 'develop' into add-cloud.vmware.convert_to_snapshot-feature
This commit is contained in:
commit
27e80e4627
644 changed files with 17255 additions and 6659 deletions
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
6
.github/PULL_REQUEST_TEMPLATE.md
vendored
|
@ -12,4 +12,10 @@ Remove this section if not relevant
|
|||
|
||||
Yes/No
|
||||
|
||||
### Commits signed with GPG?
|
||||
|
||||
Yes/No
|
||||
|
||||
Please review [Salt's Contributing Guide](https://docs.saltstack.com/en/latest/topics/development/contributing.html) for best practices.
|
||||
|
||||
See GitHub's [page on GPG signing](https://help.github.com/articles/signing-commits-using-gpg/) for more information about signing commits with GPG.
|
||||
|
|
4
.github/stale.yml
vendored
4
.github/stale.yml
vendored
|
@ -1,8 +1,8 @@
|
|||
# Probot Stale configuration file
|
||||
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
# 975 is approximately 2 years and 8 months
|
||||
daysUntilStale: 975
|
||||
# 890 is approximately 2 years and 5 months
|
||||
daysUntilStale: 890
|
||||
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
|
|
8
.gitignore
vendored
8
.gitignore
vendored
|
@ -89,3 +89,11 @@ tests/integration/cloud/providers/logs
|
|||
# Private keys from the integration tests
|
||||
tests/integration/cloud/providers/pki/minions
|
||||
/helpers/
|
||||
|
||||
# Ignore tox virtualenvs
|
||||
/.tox/
|
||||
|
||||
# Kitchen tests files
|
||||
.kitchen/
|
||||
.bundle/
|
||||
Gemfile.lock
|
||||
|
|
187
.kitchen.yml
Normal file
187
.kitchen.yml
Normal file
|
@ -0,0 +1,187 @@
|
|||
---
|
||||
<% vagrant = system('which vagrant 2>/dev/null >/dev/null') %>
|
||||
<% version = '2017.7.2' %>
|
||||
<% platformsfile = ENV['SALT_KITCHEN_PLATFORMS'] || '.kitchen/platforms.yml' %>
|
||||
<% driverfile = ENV['SALT_KITCHEN_DRIVER'] || '.kitchen/driver.yml' %>
|
||||
|
||||
<% if File.exists?(driverfile) %>
|
||||
<%= ERB.new(File.read(driverfile)).result %>
|
||||
<% else %>
|
||||
driver:
|
||||
name: docker
|
||||
use_sudo: false
|
||||
privileged: true
|
||||
username: root
|
||||
volume:
|
||||
- /var/run/docker.sock:/docker.sock
|
||||
cap_add:
|
||||
- sys_admin
|
||||
disable_upstart: false
|
||||
provision_command:
|
||||
- echo 'L /run/docker.sock - - - - /docker.sock' > /etc/tmpfiles.d/docker.conf
|
||||
<% end %>
|
||||
|
||||
sudo: false
|
||||
provisioner:
|
||||
name: salt_solo
|
||||
salt_install: bootstrap
|
||||
salt_version: latest
|
||||
salt_bootstrap_url: https://bootstrap.saltstack.com
|
||||
salt_bootstrap_options: -X stable <%= version %>
|
||||
log_level: info
|
||||
require_chef: false
|
||||
remote_states:
|
||||
name: git://github.com/gtmanfred/salt-jenkins.git
|
||||
branch: master
|
||||
repo: git
|
||||
testingdir: /testing
|
||||
salt_copy_filter:
|
||||
- .bundle
|
||||
- .git
|
||||
- .gitignore
|
||||
- .kitchen
|
||||
- .kitchen.yml
|
||||
- Gemfile
|
||||
- Gemfile.lock
|
||||
- README.rst
|
||||
- .travis.yml
|
||||
state_top:
|
||||
base:
|
||||
"*":
|
||||
- git.salt
|
||||
- kitchen
|
||||
<% if File.exists?(platformsfile) %>
|
||||
<%= ERB.new(File.read(platformsfile)).result %>
|
||||
<% else %>
|
||||
platforms:
|
||||
- name: fedora
|
||||
driver_config:
|
||||
image: fedora:latest
|
||||
run_command: /usr/lib/systemd/systemd
|
||||
provisioner:
|
||||
salt_bootstrap_options: -X git v<%= version %> >/dev/null
|
||||
- name: centos-7
|
||||
driver_config:
|
||||
run_command: /usr/lib/systemd/systemd
|
||||
- name: centos-6
|
||||
driver_config:
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- yum install -y upstart
|
||||
provisioner:
|
||||
salt_bootstrap_options: -P -y -x python2.7 -X git v<%= version %> >/dev/null
|
||||
- name: ubuntu-rolling
|
||||
driver_config:
|
||||
image: ubuntu:rolling
|
||||
run_command: /lib/systemd/systemd
|
||||
provisioner:
|
||||
salt_bootstrap_url: https://raw.githubusercontent.com/saltstack/salt-bootstrap/develop/bootstrap-salt.sh
|
||||
- name: ubuntu-16.04
|
||||
driver_config:
|
||||
run_command: /lib/systemd/systemd
|
||||
- name: ubuntu-14.04
|
||||
driver_config:
|
||||
run_command: /sbin/init
|
||||
provision_command:
|
||||
- rm -f /sbin/initctl
|
||||
- dpkg-divert --local --rename --remove /sbin/initctl
|
||||
- name: debian-8
|
||||
driver_config:
|
||||
run_command: /lib/systemd/systemd
|
||||
provision_command:
|
||||
- apt-get install -y dbus
|
||||
- echo 'L /run/docker.sock - - - - /docker.sock' > /etc/tmpfiles.d/docker.conf
|
||||
- name: debian-9
|
||||
driver_config:
|
||||
run_command: /lib/systemd/systemd
|
||||
- name: arch
|
||||
driver_config:
|
||||
image: base/archlinux
|
||||
run_command: /usr/lib/systemd/systemd
|
||||
provision_command:
|
||||
- pacman -Syu --noconfirm systemd
|
||||
- systemctl enable sshd
|
||||
- echo 'L /run/docker.sock - - - - /docker.sock' > /etc/tmpfiles.d/docker.conf
|
||||
provisioner:
|
||||
salt_bootstrap_options: -X git v<%= version %> >/dev/null
|
||||
- name: opensuse
|
||||
driver_config:
|
||||
run_command: /usr/lib/systemd/systemd
|
||||
provision_command:
|
||||
- systemctl enable sshd.service
|
||||
- echo 'L /run/docker.sock - - - - /docker.sock' > /etc/tmpfiles.d/docker.conf
|
||||
provisioner:
|
||||
salt_bootstrap_options: -X git v<%= version %> >/dev/null
|
||||
<% if vagrant != false %>
|
||||
- name: windows-2012r2
|
||||
driver:
|
||||
box: mwrock/Windows2012R2
|
||||
communicator: winrm
|
||||
name: vagrant
|
||||
gui: true
|
||||
username: administrator
|
||||
password: Pass@word1
|
||||
provisioner:
|
||||
init_environment: |
|
||||
Clear-Host
|
||||
$AddedLocation ="c:\salt"
|
||||
$Reg = "Registry::HKLM\System\CurrentControlSet\Control\Session Manager\Environment"
|
||||
$OldPath = (Get-ItemProperty -Path "$Reg" -Name PATH).Path
|
||||
$NewPath= $OldPath + ’;’ + $AddedLocation
|
||||
Set-ItemProperty -Path "$Reg" -Name PATH –Value $NewPath
|
||||
salt_bootstrap_url: https://raw.githubusercontent.com/saltstack/salt-bootstrap/develop/bootstrap-salt.ps1
|
||||
salt_bootstrap_options: ''
|
||||
- name: windows-2016
|
||||
driver:
|
||||
box: mwrock/Windows2016
|
||||
communicator: winrm
|
||||
name: vagrant
|
||||
username: Vagrant
|
||||
password: vagrant
|
||||
gui: true
|
||||
provisioner:
|
||||
init_environment: |
|
||||
Clear-Host
|
||||
$AddedLocation ="c:\salt;c:\salt\bin\Scripts"
|
||||
$Reg = "Registry::HKLM\System\CurrentControlSet\Control\Session Manager\Environment"
|
||||
$OldPath = (Get-ItemProperty -Path "$Reg" -Name PATH).Path
|
||||
$NewPath= $OldPath + ’;’ + $AddedLocation
|
||||
Set-ItemProperty -Path "$Reg" -Name PATH –Value $NewPath
|
||||
salt_bootstrap_url: https://raw.githubusercontent.com/saltstack/salt-bootstrap/develop/bootstrap-salt.ps1
|
||||
salt_bootstrap_options: ''
|
||||
<% end %>
|
||||
<% end %>
|
||||
suites:
|
||||
- name: py2
|
||||
provisioner:
|
||||
pillars:
|
||||
top.sls:
|
||||
base:
|
||||
"*":
|
||||
- jenkins
|
||||
jenkins.sls:
|
||||
testing_dir: /tmp/kitchen/testing
|
||||
clone_repo: false
|
||||
salttesting_namespec: salttesting==2017.6.1
|
||||
- name: py3
|
||||
provisioner:
|
||||
pillars:
|
||||
top.sls:
|
||||
base:
|
||||
"*":
|
||||
- jenkins
|
||||
jenkins.sls:
|
||||
testing_dir: /tmp/kitchen/testing
|
||||
clone_repo: false
|
||||
py3: true
|
||||
salttesting_namespec: salttesting==2017.6.1
|
||||
verifier:
|
||||
name: shell
|
||||
remote_exec: true
|
||||
sudo: false
|
||||
live_stream: {}
|
||||
<% if ENV['TESTOPTS'].nil? %>
|
||||
command: '$(kitchen) /tmp/kitchen/testing/tests/runtests.py --run-destructive --sysinfo --transport=zeromq --output-columns=80 --ssh --coverage-xml=/tmp/coverage.xml --xml=/tmp/xml-unittests-output'
|
||||
<% else %>
|
||||
command: '$(kitchen) /tmp/kitchen/testing/tests/runtests.py --run-destructive --output-columns 80 <%= ENV["TESTOPTS"] %>'
|
||||
<% end %>
|
|
@ -258,8 +258,8 @@ ignore-imports=no
|
|||
|
||||
|
||||
[BASIC]
|
||||
# Required attributes for module, separated by a comma
|
||||
required-attributes=
|
||||
# Required attributes for module, separated by a comma (will be removed in Pylint 2.0)
|
||||
#required-attributes=
|
||||
|
||||
# List of builtins function names that should not be used, separated by a comma
|
||||
bad-functions=map,filter,apply,input
|
||||
|
@ -365,7 +365,8 @@ spelling-store-unknown-words=no
|
|||
[CLASSES]
|
||||
# List of interface methods to ignore, separated by a comma. This is used for
|
||||
# instance to not check methods defines in Zope's Interface base class.
|
||||
ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
|
||||
# Will be removed in Pylint 2.0
|
||||
#ignore-iface-methods=isImplementedBy,deferred,extends,names,namesAndDescriptions,queryDescriptionFor,getBases,getDescriptionFor,getDoc,getName,getTaggedValue,getTaggedValueTags,isEqualOrExtendedBy,setTaggedValue,isImplementedByInstancesOf,adaptWith,is_implemented_by
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,__new__,setUp
|
||||
|
|
23
Gemfile
Normal file
23
Gemfile
Normal file
|
@ -0,0 +1,23 @@
|
|||
# This file is only used for running the test suite with kitchen-salt.
|
||||
|
||||
source "https://rubygems.org"
|
||||
|
||||
gem "test-kitchen"
|
||||
gem "kitchen-salt", :git => 'https://github.com/saltstack/kitchen-salt.git'
|
||||
gem 'git'
|
||||
|
||||
group :docker do
|
||||
gem 'kitchen-docker', :git => 'https://github.com/test-kitchen/kitchen-docker.git'
|
||||
end
|
||||
|
||||
group :opennebula do
|
||||
gem 'kitchen-opennebula', :git => 'https://github.com/gtmanfred/kitchen-opennebula.git'
|
||||
gem 'xmlrpc'
|
||||
end
|
||||
|
||||
group :windows do
|
||||
gem 'vagrant-wrapper'
|
||||
gem 'kitchen-vagrant'
|
||||
gem 'winrm', '~>2.0'
|
||||
gem 'winrm-fs', '~>1.0'
|
||||
end
|
|
@ -44,6 +44,11 @@ may take a few moments for someone to reply.
|
|||
|
||||
`<http://webchat.freenode.net/?channels=salt&uio=Mj10cnVlJjk9dHJ1ZSYxMD10cnVl83>`_
|
||||
|
||||
**SaltStack Slack** - Alongside IRC is our SaltStack Community Slack for the
|
||||
SaltStack Working groups. Use the following link to request an invitation.
|
||||
|
||||
`<https://saltstackcommunity.herokuapp.com/>`_
|
||||
|
||||
**Mailing List** - The SaltStack community users mailing list is hosted by
|
||||
Google groups. Anyone can post to ask questions about SaltStack products and
|
||||
anyone can help answer. Join the conversation!
|
||||
|
|
|
@ -464,11 +464,13 @@
|
|||
|
||||
##### Salt-SSH Configuration #####
|
||||
##########################################
|
||||
# Define the default salt-ssh roster module to use
|
||||
#roster: flat
|
||||
|
||||
# Pass in an alternative location for the salt-ssh roster file
|
||||
# Pass in an alternative location for the salt-ssh `flat` roster file
|
||||
#roster_file: /etc/salt/roster
|
||||
|
||||
# Define locations for roster files so they can be chosen when using Salt API.
|
||||
# Define locations for `flat` roster files so they can be chosen when using Salt API.
|
||||
# An administrator can place roster files into these locations. Then when
|
||||
# calling Salt API, parameter 'roster_file' should contain a relative path to
|
||||
# these locations. That is, "roster_file=/foo/roster" will be resolved as
|
||||
|
|
|
@ -438,11 +438,13 @@ syndic_user: salt
|
|||
|
||||
##### Salt-SSH Configuration #####
|
||||
##########################################
|
||||
# Define the default salt-ssh roster module to use
|
||||
#roster: flat
|
||||
|
||||
# Pass in an alternative location for the salt-ssh roster file
|
||||
# Pass in an alternative location for the salt-ssh `flat` roster file
|
||||
#roster_file: /etc/salt/roster
|
||||
|
||||
# Define locations for roster files so they can be chosen when using Salt API.
|
||||
# Define locations for `flat` roster files so they can be chosen when using Salt API.
|
||||
# An administrator can place roster files into these locations. Then when
|
||||
# calling Salt API, parameter 'roster_file' should contain a relative path to
|
||||
# these locations. That is, "roster_file=/foo/roster" will be resolved as
|
||||
|
|
BIN
doc/_themes/saltstack2/static/images/DOCBANNER.jpg
vendored
BIN
doc/_themes/saltstack2/static/images/DOCBANNER.jpg
vendored
Binary file not shown.
Before Width: | Height: | Size: 790 KiB After Width: | Height: | Size: 438 KiB |
|
@ -29818,7 +29818,7 @@ If the master seems to be unresponsive, a SIGUSR1 can be passed to the
|
|||
salt\-master threads to display what piece of code is executing. This debug
|
||||
information can be invaluable in tracking down bugs.
|
||||
.sp
|
||||
To pass a SIGUSR1 to the master, first make sure the minion is running in the
|
||||
To pass a SIGUSR1 to the master, first make sure the master is running in the
|
||||
foreground. Stop the service if it is running as a daemon, and start it in the
|
||||
foreground like so:
|
||||
.INDENT 0.0
|
||||
|
|
|
@ -34,6 +34,7 @@ Full list of Salt Cloud modules
|
|||
scaleway
|
||||
softlayer
|
||||
softlayer_hw
|
||||
vagrant
|
||||
virtualbox
|
||||
vmware
|
||||
vultrpy
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
===============================
|
||||
==============================
|
||||
salt.cloud.clouds.digitalocean
|
||||
===============================
|
||||
==============================
|
||||
|
||||
.. automodule:: salt.cloud.clouds.digitalocean
|
||||
:members:
|
6
doc/ref/clouds/all/salt.cloud.clouds.vagrant.rst
Normal file
6
doc/ref/clouds/all/salt.cloud.clouds.vagrant.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
=========================
|
||||
salt.cloud.clouds.vagrant
|
||||
=========================
|
||||
|
||||
.. automodule:: salt.cloud.clouds.vagrant
|
||||
:members:
|
|
@ -718,7 +718,7 @@ Note that ping_on_rotate may cause high load on the master immediately after
|
|||
the key rotation event as minions reconnect. Consider this carefully if this
|
||||
salt master is managing a large number of minions.
|
||||
|
||||
.. code-black:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
ping_on_rotate: False
|
||||
|
||||
|
@ -904,7 +904,7 @@ is set to ``tcp`` by default on Windows.
|
|||
|
||||
ipc_mode: ipc
|
||||
|
||||
.. conf_master::
|
||||
.. conf_master:: tcp_master_pub_port
|
||||
|
||||
``tcp_master_pub_port``
|
||||
-----------------------
|
||||
|
@ -963,6 +963,19 @@ The TCP port for ``mworkers`` to connect to on the master.
|
|||
Salt-SSH Configuration
|
||||
======================
|
||||
|
||||
.. conf_master:: roster
|
||||
|
||||
``roster``
|
||||
---------------
|
||||
|
||||
Default: ``flat``
|
||||
|
||||
Define the default salt-ssh roster module to use
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
roster: cache
|
||||
|
||||
.. conf_master:: roster_file
|
||||
|
||||
``roster_file``
|
||||
|
@ -970,12 +983,31 @@ Salt-SSH Configuration
|
|||
|
||||
Default: ``/etc/salt/roster``
|
||||
|
||||
Pass in an alternative location for the salt-ssh roster file.
|
||||
Pass in an alternative location for the salt-ssh `flat` roster file.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
roster_file: /root/roster
|
||||
|
||||
.. conf_master:: roster_file
|
||||
|
||||
``rosters``
|
||||
---------------
|
||||
|
||||
Default: None
|
||||
|
||||
Define locations for `flat` roster files so they can be chosen when using Salt API.
|
||||
An administrator can place roster files into these locations.
|
||||
Then when calling Salt API, parameter 'roster_file' should contain a relative path to these locations.
|
||||
That is, "roster_file=/foo/roster" will be resolved as "/etc/salt/roster.d/foo/roster" etc.
|
||||
This feature prevents passing insecure custom rosters through the Salt API.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
rosters:
|
||||
- /etc/salt/roster.d
|
||||
- /opt/salt/some/more/rosters
|
||||
|
||||
.. conf_master:: ssh_passwd
|
||||
|
||||
``ssh_passwd``
|
||||
|
@ -4205,6 +4237,7 @@ Default: ``10``
|
|||
The number of workers for the runner/wheel in the reactor.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
reactor_worker_threads: 10
|
||||
|
||||
.. conf_master:: reactor_worker_hwm
|
||||
|
|
|
@ -1196,7 +1196,7 @@ be able to execute a certain module. The ``sys`` module is built into the minion
|
|||
and cannot be disabled.
|
||||
|
||||
This setting can also tune the minion. Because all modules are loaded into system
|
||||
memory, disabling modules will lover the minion's memory footprint.
|
||||
memory, disabling modules will lower the minion's memory footprint.
|
||||
|
||||
Modules should be specified according to their file name on the system and not by
|
||||
their virtual name. For example, to disable ``cmd``, use the string ``cmdmod`` which
|
||||
|
@ -2387,6 +2387,7 @@ Default: ``10``
|
|||
The number of workers for the runner/wheel in the reactor.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
reactor_worker_threads: 10
|
||||
|
||||
.. conf_minion:: reactor_worker_hwm
|
||||
|
|
|
@ -299,6 +299,7 @@ execution modules
|
|||
openstack_mng
|
||||
openvswitch
|
||||
opkg
|
||||
opsgenie
|
||||
oracle
|
||||
osquery
|
||||
out
|
||||
|
@ -432,6 +433,7 @@ execution modules
|
|||
uptime
|
||||
useradd
|
||||
uwsgi
|
||||
vagrant
|
||||
varnish
|
||||
vault
|
||||
vbox_guest
|
||||
|
|
6
doc/ref/modules/all/salt.modules.opsgenie.rst
Normal file
6
doc/ref/modules/all/salt.modules.opsgenie.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
===================
|
||||
salt.modules.opsgenie
|
||||
===================
|
||||
|
||||
.. automodule:: salt.modules.opsgenie
|
||||
:members:
|
6
doc/ref/modules/all/salt.modules.vagrant.rst
Normal file
6
doc/ref/modules/all/salt.modules.vagrant.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
====================
|
||||
salt.modules.vagrant
|
||||
====================
|
||||
|
||||
.. automodule:: salt.modules.vagrant
|
||||
:members:
|
|
@ -46,5 +46,6 @@ returner modules
|
|||
splunk
|
||||
sqlite3_return
|
||||
syslog_return
|
||||
telegram_return
|
||||
xmpp_return
|
||||
zabbix_return
|
||||
|
|
|
@ -188,6 +188,7 @@ state modules
|
|||
openstack_config
|
||||
openvswitch_bridge
|
||||
openvswitch_port
|
||||
opsgenie
|
||||
pagerduty
|
||||
pagerduty_escalation_policy
|
||||
pagerduty_schedule
|
||||
|
@ -267,6 +268,7 @@ state modules
|
|||
tuned
|
||||
uptime
|
||||
user
|
||||
vagrant
|
||||
vault
|
||||
vbox_guest
|
||||
victorops
|
||||
|
|
6
doc/ref/states/all/salt.states.opsgenie.rst
Normal file
6
doc/ref/states/all/salt.states.opsgenie.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
=====================
|
||||
salt.states.opsgenie
|
||||
=====================
|
||||
|
||||
.. automodule:: salt.states.opsgenie
|
||||
:members:
|
6
doc/ref/states/all/salt.states.vagrant.rst
Normal file
6
doc/ref/states/all/salt.states.vagrant.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
===================
|
||||
salt.states.vagrant
|
||||
===================
|
||||
|
||||
.. automodule:: salt.states.vagrant
|
||||
:members:
|
|
@ -6,7 +6,7 @@ Introduced in Salt version ``2017.7.0`` it is now possible to run select states
|
|||
in parallel. This is accomplished very easily by adding the ``parallel: True``
|
||||
option to your state declaration:
|
||||
|
||||
.. code_block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
nginx:
|
||||
service.running:
|
||||
|
@ -24,7 +24,7 @@ state to finish.
|
|||
|
||||
Given this example:
|
||||
|
||||
.. code_block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
sleep 10:
|
||||
cmd.run:
|
||||
|
@ -51,7 +51,7 @@ actually speed things up.
|
|||
To run the above state much faster make sure that the ``sleep 5`` is evaluated
|
||||
before the ``nginx`` state
|
||||
|
||||
.. code_block:: yaml
|
||||
.. code-block:: yaml
|
||||
|
||||
sleep 10:
|
||||
cmd.run:
|
||||
|
@ -74,16 +74,16 @@ also complete.
|
|||
Things to be Careful of
|
||||
=======================
|
||||
|
||||
Parallel States does not prevent you from creating parallel conflicts on your
|
||||
Parallel States do not prevent you from creating parallel conflicts on your
|
||||
system. This means that if you start multiple package installs using Salt then
|
||||
the package manager will block or fail. If you attempt to manage the same file
|
||||
with multiple states in parallel then the result can produce an unexpected
|
||||
file.
|
||||
|
||||
Make sure that the states you choose to run in parallel do not conflict, or
|
||||
else, like in and parallel programming environment, the outcome may not be
|
||||
else, like in any parallel programming environment, the outcome may not be
|
||||
what you expect. Doing things like just making all states run in parallel
|
||||
will almost certinly result in unexpected behavior.
|
||||
will almost certainly result in unexpected behavior.
|
||||
|
||||
With that said, running states in parallel should be safe the vast majority
|
||||
of the time and the most likely culprit for unexpected behavior is running
|
||||
|
|
|
@ -146,24 +146,24 @@ library. The following two lines set up the imports:
|
|||
.. code-block:: python
|
||||
|
||||
from salt.cloud.libcloudfuncs import * # pylint: disable=W0614,W0401
|
||||
import salt.utils
|
||||
import salt.utils.functools
|
||||
|
||||
And then a series of declarations will make the necessary functions available
|
||||
within the cloud module.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
get_size = salt.utils.namespaced_function(get_size, globals())
|
||||
get_image = salt.utils.namespaced_function(get_image, globals())
|
||||
avail_locations = salt.utils.namespaced_function(avail_locations, globals())
|
||||
avail_images = salt.utils.namespaced_function(avail_images, globals())
|
||||
avail_sizes = salt.utils.namespaced_function(avail_sizes, globals())
|
||||
script = salt.utils.namespaced_function(script, globals())
|
||||
destroy = salt.utils.namespaced_function(destroy, globals())
|
||||
list_nodes = salt.utils.namespaced_function(list_nodes, globals())
|
||||
list_nodes_full = salt.utils.namespaced_function(list_nodes_full, globals())
|
||||
list_nodes_select = salt.utils.namespaced_function(list_nodes_select, globals())
|
||||
show_instance = salt.utils.namespaced_function(show_instance, globals())
|
||||
get_size = salt.utils.functools.namespaced_function(get_size, globals())
|
||||
get_image = salt.utils.functools.namespaced_function(get_image, globals())
|
||||
avail_locations = salt.utils.functools.namespaced_function(avail_locations, globals())
|
||||
avail_images = salt.utils.functools.namespaced_function(avail_images, globals())
|
||||
avail_sizes = salt.utils.functools.namespaced_function(avail_sizes, globals())
|
||||
script = salt.utils.functools.namespaced_function(script, globals())
|
||||
destroy = salt.utils.functools.namespaced_function(destroy, globals())
|
||||
list_nodes = salt.utils.functools.namespaced_function(list_nodes, globals())
|
||||
list_nodes_full = salt.utils.functools.namespaced_function(list_nodes_full, globals())
|
||||
list_nodes_select = salt.utils.functools.namespaced_function(list_nodes_select, globals())
|
||||
show_instance = salt.utils.functools.namespaced_function(show_instance, globals())
|
||||
|
||||
If necessary, these functions may be replaced by removing the appropriate
|
||||
declaration line, and then adding the function as normal.
|
||||
|
|
|
@ -540,6 +540,17 @@ machines which are already installed, but not Salted. For more information about
|
|||
this driver and for configuration examples, please see the
|
||||
:ref:`Gettting Started with Saltify <getting-started-with-saltify>` documentation.
|
||||
|
||||
.. _config_vagrant:
|
||||
|
||||
Vagrant
|
||||
-------
|
||||
|
||||
The Vagrant driver is a new, experimental driver for controlling a VagrantBox
|
||||
virtual machine, and installing Salt on it. The target host machine must be a
|
||||
working salt minion, which is controlled via the salt master using salt-api.
|
||||
For more information, see
|
||||
:ref:`Getting Started With Vagrant <getting-started-with-vagrant>`.
|
||||
|
||||
|
||||
Extending Profiles and Cloud Providers Configuration
|
||||
====================================================
|
||||
|
|
|
@ -54,6 +54,10 @@ Set up an initial profile at ``/etc/salt/cloud.profiles`` or in the
|
|||
ipv6: True
|
||||
create_dns_record: True
|
||||
userdata_file: /etc/salt/cloud.userdata.d/setup
|
||||
tags:
|
||||
- tag1
|
||||
- tag2
|
||||
- tag3
|
||||
|
||||
Locations can be obtained using the ``--list-locations`` option for the ``salt-cloud``
|
||||
command:
|
||||
|
|
|
@ -38,26 +38,30 @@ These are features that are available for almost every cloud host.
|
|||
|
||||
.. container:: scrollable
|
||||
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
| |AWS |CloudStack|Digital|EC2|GoGrid|JoyEnt|Linode|OpenStack|Parallels|Rackspace|Saltify|Softlayer|Softlayer|Aliyun|
|
||||
| |(Legacy)| |Ocean | | | | | | |(Legacy) | | |Hardware | |
|
||||
+=======================+========+==========+=======+===+======+======+======+=========+=========+=========+=======+=========+=========+======+
|
||||
|Query |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|Full Query |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|Selective Query |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|List Sizes |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|List Images |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|List Locations |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|create |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|destroy |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
| |AWS |CloudStack|Digital|EC2|GoGrid|JoyEnt|Linode|OpenStack|Parallels|Rackspace|Saltify|Vagrant|Softlayer|Softlayer|Aliyun|
|
||||
| |(Legacy)| |Ocean | | | | | | |(Legacy) | | | |Hardware | |
|
||||
+=======================+========+==========+=======+===+======+======+======+=========+=========+=========+=======+=======+=========+=========+======+
|
||||
|Query |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |[1] |[1] |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|Full Query |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |[1] |[1] |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|Selective Query |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |[1] |[1] |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|List Sizes |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |[2] |[2] |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|List Images |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|List Locations |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |[2] |[2] |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|create |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |[1] |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|destroy |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |[1] |[1] |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+-------+---------+---------+------+
|
||||
|
||||
[1] Yes, if salt-api is enabled.
|
||||
|
||||
[2] Always returns `{}`.
|
||||
|
||||
Actions
|
||||
=======
|
||||
|
@ -70,46 +74,46 @@ instance name to be passed in. For example:
|
|||
|
||||
.. container:: scrollable
|
||||
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|Actions |AWS |CloudStack|Digital|EC2|GoGrid|JoyEnt|Linode|OpenStack|Parallels|Rackspace|Saltify|Softlayer|Softlayer|Aliyun|
|
||||
| |(Legacy)| |Ocean | | | | | | |(Legacy) | | |Hardware | |
|
||||
+=======================+========+==========+=======+===+======+======+======+=========+=========+=========+=======+=========+=========+======+
|
||||
|attach_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|create_attach_volumes |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|del_tags |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|delvol_on_destroy | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|detach_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|disable_term_protect |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|enable_term_protect |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_tags |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|keepvol_on_destroy | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_keypairs | | |Yes | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|rename |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|set_tags |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|show_delvol_on_destroy | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|show_instance | | |Yes |Yes| | |Yes | |Yes | | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|show_term_protect | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|start |Yes | | |Yes| |Yes |Yes | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|stop |Yes | | |Yes| |Yes |Yes | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|take_action | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|Actions |AWS |CloudStack|Digital|EC2|GoGrid|JoyEnt|Linode|OpenStack|Parallels|Rackspace|Saltify&|Softlayer|Softlayer|Aliyun|
|
||||
| |(Legacy)| |Ocean | | | | | | |(Legacy) | Vagrant| |Hardware | |
|
||||
+=======================+========+==========+=======+===+======+======+======+=========+=========+=========+========+=========+=========+======+
|
||||
|attach_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|create_attach_volumes |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|del_tags |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|delvol_on_destroy | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|detach_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|disable_term_protect |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|enable_term_protect |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_tags |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|keepvol_on_destroy | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_keypairs | | |Yes | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|rename |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|set_tags |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|show_delvol_on_destroy | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|show_instance | | |Yes |Yes| | |Yes | |Yes | | |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|show_term_protect | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|start |Yes | | |Yes| |Yes |Yes | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|stop |Yes | | |Yes| |Yes |Yes | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|take_action | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|
||||
Functions
|
||||
=========
|
||||
|
@ -122,81 +126,83 @@ require the name of the provider to be passed in. For example:
|
|||
|
||||
.. container:: scrollable
|
||||
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|Functions |AWS |CloudStack|Digital|EC2|GoGrid|JoyEnt|Linode|OpenStack|Parallels|Rackspace|Saltify|Softlayer|Softlayer|Aliyun|
|
||||
| |(Legacy)| |Ocean | | | | | | |(Legacy) | | |Hardware | |
|
||||
+=======================+========+==========+=======+===+======+======+======+=========+=========+=========+=======+=========+=========+======+
|
||||
|block_device_mappings |Yes | | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|create_keypair | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|create_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|delete_key | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|delete_keypair | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|delete_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_image | | |Yes | | |Yes | | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_ip | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_key | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_keyid | | |Yes | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_keypair | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_networkid | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_node | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_password | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_size | | |Yes | | |Yes | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_spot_config | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|get_subnetid | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|iam_profile |Yes | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|import_key | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|key_list | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|keyname |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_availability_zones| | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_custom_images | | | | | | | | | | | |Yes | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_keys | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_nodes |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_nodes_full |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_nodes_select |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|list_vlans | | | | | | | | | | | |Yes |Yes | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|rackconnect | | | | | | | |Yes | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|reboot | | | |Yes| |Yes | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|reformat_node | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|securitygroup |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|securitygroupid | | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|show_image | | | |Yes| | | | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|show_key | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|show_keypair | | |Yes |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
|show_volume | | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+-------+---------+---------+------+
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|Functions |AWS |CloudStack|Digital|EC2|GoGrid|JoyEnt|Linode|OpenStack|Parallels|Rackspace|Saltify&|Softlayer|Softlayer|Aliyun|
|
||||
| |(Legacy)| |Ocean | | | | | | |(Legacy) | Vagrant| |Hardware | |
|
||||
+=======================+========+==========+=======+===+======+======+======+=========+=========+=========+========+=========+=========+======+
|
||||
|block_device_mappings |Yes | | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|create_keypair | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|create_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|delete_key | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|delete_keypair | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|delete_volume | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_image | | |Yes | | |Yes | | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_ip | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_key | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_keyid | | |Yes | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_keypair | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_networkid | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_node | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_password | |Yes | | | | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_size | | |Yes | | |Yes | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_spot_config | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|get_subnetid | | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|iam_profile |Yes | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|import_key | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|key_list | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|keyname |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_availability_zones| | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_custom_images | | | | | | | | | | | |Yes | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_keys | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_nodes |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_nodes_full |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_nodes_select |Yes |Yes |Yes |Yes|Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|list_vlans | | | | | | | | | | | |Yes |Yes | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|rackconnect | | | | | | | |Yes | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|reboot | | | |Yes| |Yes | | | | |[1] | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|reformat_node | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|securitygroup |Yes | | |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|securitygroupid | | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|show_image | | | |Yes| | | | |Yes | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|show_key | | | | | |Yes | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|show_keypair | | |Yes |Yes| | | | | | | | | | |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|show_volume | | | |Yes| | | | | | | | | |Yes |
|
||||
+-----------------------+--------+----------+-------+---+------+------+------+---------+---------+---------+--------+---------+---------+------+
|
||||
|
||||
[1] Yes, if salt-api is enabled.
|
||||
|
|
|
@ -129,6 +129,7 @@ Cloud Provider Specifics
|
|||
Getting Started With Scaleway <scaleway>
|
||||
Getting Started With Saltify <saltify>
|
||||
Getting Started With SoftLayer <softlayer>
|
||||
Getting Started With Vagrant <vagrant>
|
||||
Getting Started With Vexxhost <vexxhost>
|
||||
Getting Started With Virtualbox <virtualbox>
|
||||
Getting Started With VMware <vmware>
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
.. _misc-salt-cloud-options:
|
||||
|
||||
================================
|
||||
Miscellaneous Salt Cloud Options
|
||||
================================
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
Getting Started With Saltify
|
||||
============================
|
||||
|
||||
The Saltify driver is a new, experimental driver for installing Salt on existing
|
||||
The Saltify driver is a driver for installing Salt on existing
|
||||
machines (virtual or bare metal).
|
||||
|
||||
|
||||
|
@ -33,20 +33,29 @@ the salt-master:
|
|||
|
||||
However, if you wish to use the more advanced capabilities of salt-cloud, such as
|
||||
rebooting, listing, and disconnecting machines, then the salt master must fill
|
||||
the role usually performed by a vendor's cloud management system. In order to do
|
||||
that, you must configure your salt master as a salt-api server, and supply credentials
|
||||
to use it. (See ``salt-api setup`` below.)
|
||||
the role usually performed by a vendor's cloud management system. The salt master
|
||||
must be running on the salt-cloud machine, and created nodes must be connected to the
|
||||
master.
|
||||
|
||||
Additional information about which configuration options apply to which actions
|
||||
can be studied in the
|
||||
:ref:`Saltify Module documentation <saltify-module>`
|
||||
and the
|
||||
:ref:`Miscellaneous Salt Cloud Options <misc-salt-cloud-options>`
|
||||
document.
|
||||
|
||||
Profiles
|
||||
========
|
||||
|
||||
Saltify requires a profile to be configured for each machine that needs Salt
|
||||
installed. The initial profile can be set up at ``/etc/salt/cloud.profiles``
|
||||
Saltify requires a separate profile to be configured for each machine that
|
||||
needs Salt installed [#]_. The initial profile can be set up at
|
||||
``/etc/salt/cloud.profiles``
|
||||
or in the ``/etc/salt/cloud.profiles.d/`` directory. Each profile requires
|
||||
both an ``ssh_host`` and an ``ssh_username`` key parameter as well as either
|
||||
an ``key_filename`` or a ``password``.
|
||||
|
||||
.. [#] Unless you are using a map file to provide the unique parameters.
|
||||
|
||||
Profile configuration example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
@ -68,40 +77,78 @@ The machine can now be "Salted" with the following command:
|
|||
This will install salt on the machine specified by the cloud profile,
|
||||
``salt-this-machine``, and will give the machine the minion id of
|
||||
``my-machine``. If the command was executed on the salt-master, its Salt
|
||||
key will automatically be signed on the master.
|
||||
key will automatically be accepted by the master.
|
||||
|
||||
Once a salt-minion has been successfully installed on the instance, connectivity
|
||||
to it can be verified with Salt:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt my-machine test.ping
|
||||
|
||||
salt my-machine test.version
|
||||
|
||||
Destroy Options
|
||||
---------------
|
||||
|
||||
.. versionadded:: Oxygen
|
||||
|
||||
For obvious reasons, the ``destroy`` action does not actually vaporize hardware.
|
||||
If the salt master is connected using salt-api, it can tear down parts of
|
||||
the client machines. It will remove the client's key from the salt master,
|
||||
and will attempt the following options:
|
||||
If the salt master is connected, it can tear down parts of the client machines.
|
||||
It will remove the client's key from the salt master,
|
||||
and can execute the following options:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
- remove_config_on_destroy: true
|
||||
# default: true
|
||||
# Deactivate salt-minion on reboot and
|
||||
# delete the minion config and key files from its ``/etc/salt`` directory,
|
||||
# NOTE: If deactivation is unsuccessful (older Ubuntu machines) then when
|
||||
# delete the minion config and key files from its "/etc/salt" directory,
|
||||
# NOTE: If deactivation was unsuccessful (older Ubuntu machines) then when
|
||||
# salt-minion restarts it will automatically create a new, unwanted, set
|
||||
# of key files. The ``force_minion_config`` option must be used in that case.
|
||||
# of key files. Use the "force_minion_config" option to replace them.
|
||||
|
||||
- shutdown_on_destroy: false
|
||||
# default: false
|
||||
# send a ``shutdown`` command to the client.
|
||||
# last of all, send a "shutdown" command to the client.
|
||||
|
||||
Wake On LAN
|
||||
-----------
|
||||
|
||||
.. versionadded:: Oxygen
|
||||
|
||||
In addition to connecting a hardware machine to a Salt master,
|
||||
you have the option of sending a wake-on-LAN
|
||||
`magic packet`_
|
||||
to start that machine running.
|
||||
|
||||
.. _magic packet: https://en.wikipedia.org/wiki/Wake-on-LAN
|
||||
|
||||
The "magic packet" must be sent by an existing salt minion which is on
|
||||
the same network segment as the target machine. (Or your router
|
||||
must be set up especially to route WoL packets.) Your target machine
|
||||
must be set up to listen for WoL and to respond appropriatly.
|
||||
|
||||
You must provide the Salt node id of the machine which will send
|
||||
the WoL packet \(parameter ``wol_sender_node``\), and
|
||||
the hardware MAC address of the machine you intend to wake,
|
||||
\(parameter ``wake_on_lan_mac``\). If both parameters are defined,
|
||||
the WoL will be sent. The cloud master will then sleep a while
|
||||
\(parameter ``wol_boot_wait``) to give the target machine time to
|
||||
boot up before we start probing its SSH port to begin deploying
|
||||
Salt to it. The default sleep time is 30 seconds.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# /etc/salt/cloud.profiles.d/saltify.conf
|
||||
|
||||
salt-this-machine:
|
||||
ssh_host: 12.34.56.78
|
||||
ssh_username: root
|
||||
key_filename: '/etc/salt/mysshkey.pem'
|
||||
provider: my-saltify-config
|
||||
wake_on_lan_mac: '00:e0:4c:70:2a:b2' # found with ifconfig
|
||||
wol_sender_node: bevymaster # its on this network segment
|
||||
wol_boot_wait: 45 # seconds to sleep
|
||||
|
||||
Using Map Files
|
||||
---------------
|
||||
The settings explained in the section above may also be set in a map file. An
|
||||
|
@ -165,67 +212,3 @@ Return values:
|
|||
- ``True``: Credential verification succeeded
|
||||
- ``False``: Credential verification succeeded
|
||||
- ``None``: Credential verification was not attempted.
|
||||
|
||||
Provisioning salt-api
|
||||
=====================
|
||||
|
||||
In order to query or control minions it created, saltify needs to send commands
|
||||
to the salt master. It does that using the network interface to salt-api.
|
||||
|
||||
The salt-api is not enabled by default. The following example will provide a
|
||||
simple installation.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# file /etc/salt/cloud.profiles.d/my_saltify_profiles.conf
|
||||
hw_41: # a theoretical example hardware machine
|
||||
ssh_host: 10.100.9.41 # the hard address of your target
|
||||
ssh_username: vagrant # a user name which has passwordless sudo
|
||||
password: vagrant # on your target machine
|
||||
provider: my_saltify_provider
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# file /etc/salt/cloud.providers.d/saltify_provider.conf
|
||||
my_saltify_provider:
|
||||
driver: saltify
|
||||
eauth: pam
|
||||
username: vagrant # supply some sudo-group-member's name
|
||||
password: vagrant # and password on the salt master
|
||||
minion:
|
||||
master: 10.100.9.5 # the hard address of the master
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# file /etc/salt/master.d/auth.conf
|
||||
# using salt-api ... members of the 'sudo' group can do anything ...
|
||||
external_auth:
|
||||
pam:
|
||||
sudo%:
|
||||
- .*
|
||||
- '@wheel'
|
||||
- '@runner'
|
||||
- '@jobs'
|
||||
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# file /etc/salt/master.d/api.conf
|
||||
# see https://docs.saltstack.com/en/latest/ref/netapi/all/salt.netapi.rest_cherrypy.html
|
||||
rest_cherrypy:
|
||||
host: localhost
|
||||
port: 8000
|
||||
ssl_crt: /etc/pki/tls/certs/localhost.crt
|
||||
ssl_key: /etc/pki/tls/certs/localhost.key
|
||||
thread_pool: 30
|
||||
socket_queue_size: 10
|
||||
|
||||
|
||||
Start your target machine as a Salt minion named "node41" by:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
$ sudo salt-cloud -p hw_41 node41
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ Set up an initial profile at /etc/salt/cloud.profiles or in the /etc/salt/cloud.
|
|||
|
||||
.. code-block:: yaml
|
||||
|
||||
scalewa-ubuntu:
|
||||
scaleway-ubuntu:
|
||||
provider: my-scaleway-config
|
||||
image: Ubuntu Trusty (14.04 LTS)
|
||||
|
||||
|
|
|
@ -94,6 +94,8 @@ Set up an initial profile at ``/etc/salt/cloud.profiles``:
|
|||
private_vlan: 396
|
||||
private_network: True
|
||||
private_ssh: True
|
||||
# Use a dedicated host instead of cloud
|
||||
dedicated_host_id: 1234
|
||||
# May be used _instead_of_ image
|
||||
global_identifier: 320d8be5-46c0-dead-cafe-13e3c51
|
||||
|
||||
|
@ -334,9 +336,21 @@ it can be verified with Salt:
|
|||
|
||||
# salt 'myserver.example.com' test.ping
|
||||
|
||||
|
||||
Cloud Profiles
|
||||
Dedicated Host
|
||||
~~~~~~~~~~~~~~
|
||||
Soflayer allows the creation of new VMs in a dedicated host. This means that
|
||||
you can order and pay a fixed amount for a bare metal dedicated host and use
|
||||
it to provision as many VMs as you can fit in there. If you want your VMs to
|
||||
be launched in a dedicated host, instead of Sofltayer's cloud, set the
|
||||
``dedicated_host_id`` parameter in your profile.
|
||||
|
||||
dedicated_host_id
|
||||
-----------------
|
||||
The id of the dedicated host where the VMs should be created. If not set, VMs
|
||||
will be created in Softlayer's cloud instead.
|
||||
|
||||
Bare metal Profiles
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
Set up an initial profile at ``/etc/salt/cloud.profiles``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
|
269
doc/topics/cloud/vagrant.rst
Normal file
269
doc/topics/cloud/vagrant.rst
Normal file
|
@ -0,0 +1,269 @@
|
|||
.. _getting-started-with-vagrant:
|
||||
|
||||
============================
|
||||
Getting Started With Vagrant
|
||||
============================
|
||||
|
||||
The Vagrant driver is a new, experimental driver for spinning up a VagrantBox
|
||||
virtual machine, and installing Salt on it.
|
||||
|
||||
Dependencies
|
||||
============
|
||||
The Vagrant driver itself has no external dependencies.
|
||||
|
||||
The machine which will host the VagrantBox must be an already existing minion
|
||||
of the cloud server's Salt master.
|
||||
It must have Vagrant_ installed, and a Vagrant-compatible virtual machine engine,
|
||||
such as VirtualBox_.
|
||||
(Note: The Vagrant driver does not depend on the salt-cloud VirtualBox driver in any way.)
|
||||
|
||||
.. _Vagrant: https://www.vagrantup.com/
|
||||
.. _VirtualBox: https://www.virtualbox.org/
|
||||
|
||||
\[Caution: The version of Vagrant packaged for ``apt install`` in Ubuntu 16.04 will not connect a bridged
|
||||
network adapter correctly. Use a version downloaded directly from the web site.\]
|
||||
|
||||
Include the Vagrant guest editions plugin:
|
||||
``vagrant plugin install vagrant-vbguest``.
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
Configuration of the client virtual machine (using VirtualBox, VMware, etc)
|
||||
will be done by Vagrant as specified in the Vagrantfile on the host machine.
|
||||
|
||||
Salt-cloud will push the commands to install and provision a salt minion on
|
||||
the virtual machine, so you need not (perhaps **should** not) provision salt
|
||||
in your Vagrantfile, in most cases.
|
||||
|
||||
If, however, your cloud master cannot open an SSH connection to the child VM,
|
||||
you may **need** to let Vagrant provision the VM with Salt, and use some other
|
||||
method (such as passing a pillar dictionary to the VM) to pass the master's
|
||||
IP address to the VM. The VM can then attempt to reach the salt master in the
|
||||
usual way for non-cloud minions. Specify the profile configuration argument
|
||||
as ``deploy: False`` to prevent the cloud master from trying.
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# Note: This example is for /etc/salt/cloud.providers file or any file in
|
||||
# the /etc/salt/cloud.providers.d/ directory.
|
||||
|
||||
my-vagrant-config:
|
||||
minion:
|
||||
master: 111.222.333.444
|
||||
provider: vagrant
|
||||
|
||||
|
||||
Because the Vagrant driver needs a place to store the mapping between the
|
||||
node name you use for Salt commands and the Vagrantfile which controls the VM,
|
||||
you must configure your salt minion as a Salt smb server.
|
||||
(See `host provisioning example`_ below.)
|
||||
|
||||
Profiles
|
||||
========
|
||||
|
||||
Vagrant requires a profile to be configured for each machine that needs Salt
|
||||
installed. The initial profile can be set up at ``/etc/salt/cloud.profiles``
|
||||
or in the ``/etc/salt/cloud.profiles.d/`` directory.
|
||||
|
||||
Each profile requires a ``vagrantfile`` parameter. If the Vagrantfile has
|
||||
definitions for `multiple machines`_ then you need a ``machine`` parameter,
|
||||
|
||||
.. _`multiple machines`: https://www.vagrantup.com/docs/multi-machine/
|
||||
|
||||
Salt-cloud uses SSH to provision the minion. There must be a routable path
|
||||
from the cloud master to the VM. Usually, you will want to use
|
||||
a bridged network adapter for SSH. The address may not be known until
|
||||
DHCP assigns it. If ``ssh_host`` is not defined, and ``target_network``
|
||||
is defined, the driver will attempt to read the address from the output
|
||||
of an ``ifconfig`` command. Lacking either setting,
|
||||
the driver will try to use the value Vagrant returns as its ``ssh_host``,
|
||||
which will work only if the cloud master is running somewhere on the same host.
|
||||
|
||||
The ``target_network`` setting should be used
|
||||
to identify the IP network your bridged adapter is expected to appear on.
|
||||
Use CIDR notation, like ``target_network: '2001:DB8::/32'``
|
||||
or ``target_network: '192.0.2.0/24'``.
|
||||
|
||||
Profile configuration example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# /etc/salt/cloud.profiles.d/vagrant.conf
|
||||
|
||||
vagrant-machine:
|
||||
host: my-vhost # the Salt id of the virtual machine's host computer.
|
||||
provider: my-vagrant-config
|
||||
cwd: /srv/machines # the path to your Virtualbox file.
|
||||
vagrant_runas: my-username # the username who defined the Vagrantbox on the host
|
||||
# vagrant_up_timeout: 300 # (seconds) timeout for cmd.run of the "vagrant up" command
|
||||
# vagrant_provider: '' # option for "vagrant up" like: "--provider vmware_fusion"
|
||||
# ssh_host: None # "None" means try to find the routable IP address from "ifconfig"
|
||||
# ssh_username: '' # also required when ssh_host is used.
|
||||
# target_network: None # Expected CIDR address range of your bridged network
|
||||
# force_minion_config: false # Set "true" to re-purpose an existing VM
|
||||
|
||||
The machine can now be created and configured with the following command:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt-cloud -p vagrant-machine my-id
|
||||
|
||||
This will create the machine specified by the cloud profile
|
||||
``vagrant-machine``, and will give the machine the minion id of
|
||||
``my-id``. If the cloud master is also the salt-master, its Salt
|
||||
key will automatically be accepted on the master.
|
||||
|
||||
Once a salt-minion has been successfully installed on the instance, connectivity
|
||||
to it can be verified with Salt:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
salt my-id test.ping
|
||||
|
||||
.. _host provisioning example:
|
||||
|
||||
Provisioning a Vagrant cloud host (example)
|
||||
===========================================
|
||||
|
||||
In order to query or control minions it created, each host
|
||||
minion needs to track the Salt node names associated with
|
||||
any guest virtual machines on it.
|
||||
It does that using a Salt sdb database.
|
||||
|
||||
The Salt sdb is not configured by default. The following example shows a
|
||||
simple installation.
|
||||
|
||||
This example assumes:
|
||||
|
||||
- you are on a large network using the 10.x.x.x IP address space
|
||||
- your Salt master's Salt id is "bevymaster"
|
||||
- it will also be your salt-cloud controller
|
||||
- it is at hardware address 10.124.30.7
|
||||
- it is running a recent Debian family Linux (raspbian)
|
||||
- your workstation is a Salt minion of bevymaster
|
||||
- your workstation's minion id is "my_laptop"
|
||||
- VirtualBox has been installed on "my_laptop" (apt install is okay)
|
||||
- Vagrant was installed from vagrantup.com. (not the 16.04 Ubuntu apt)
|
||||
- "my_laptop" has done "vagrant plugin install vagrant-vbguest"
|
||||
- the VM you want to start is on "my_laptop" at "/home/my_username/Vagrantfile"
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# file /etc/salt/minion.d/vagrant_sdb.conf on host computer "my_laptop"
|
||||
# -- this sdb database is required by the Vagrant module --
|
||||
vagrant_sdb_data: # The sdb database must have this name.
|
||||
driver: sqlite3 # Let's use SQLite to store the data ...
|
||||
database: /var/cache/salt/vagrant.sqlite # ... in this file ...
|
||||
table: sdb # ... using this table name.
|
||||
create_table: True # if not present
|
||||
|
||||
Remember to re-start your minion after changing its configuration files...
|
||||
|
||||
``sudo systemctl restart salt-minion``
|
||||
|
||||
.. code-block:: ruby
|
||||
|
||||
# -*- mode: ruby -*-
|
||||
# file /home/my_username/Vagrantfile on host computer "my_laptop"
|
||||
BEVY = "bevy1"
|
||||
DOMAIN = BEVY + ".test" # .test is an ICANN reserved non-public TLD
|
||||
|
||||
# must supply a list of names to avoid Vagrant asking for interactive input
|
||||
def get_good_ifc() # try to find a working Ubuntu network adapter name
|
||||
addr_infos = Socket.getifaddrs
|
||||
addr_infos.each do |info|
|
||||
a = info.addr
|
||||
if a and a.ip? and not a.ip_address.start_with?("127.")
|
||||
return info.name
|
||||
end
|
||||
end
|
||||
return "eth0" # fall back to an old reliable name
|
||||
end
|
||||
|
||||
Vagrant.configure(2) do |config|
|
||||
config.ssh.forward_agent = true # so you can use git ssh://...
|
||||
|
||||
# add a bridged network interface. (try to detect name, then guess MacOS names, too)
|
||||
interface_guesses = [get_good_ifc(), 'en0: Ethernet', 'en1: Wi-Fi (AirPort)']
|
||||
config.vm.network "public_network", bridge: interface_guesses
|
||||
if ARGV[0] == "up"
|
||||
puts "Trying bridge network using interfaces: #{interface_guesses}"
|
||||
end
|
||||
config.vm.provision "shell", inline: "ip address", run: "always" # make user feel good
|
||||
|
||||
# . . . . . . . . . . . . Define machine QUAIL1 . . . . . . . . . . . . . .
|
||||
config.vm.define "quail1", primary: true do |quail_config|
|
||||
quail_config.vm.box = "boxesio/xenial64-standard" # a public VMware & Virtualbox box
|
||||
quail_config.vm.hostname = "quail1." + DOMAIN # supply a name in our bevy
|
||||
quail_config.vm.provider "virtualbox" do |v|
|
||||
v.memory = 1024 # limit memory for the virtual box
|
||||
v.cpus = 1
|
||||
v.linked_clone = true # make a soft copy of the base Vagrant box
|
||||
v.customize ["modifyvm", :id, "--natnet1", "192.168.128.0/24"] # do not use 10.x network for NAT
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# file /etc/salt/cloud.profiles.d/my_vagrant_profiles.conf on bevymaster
|
||||
q1:
|
||||
host: my_laptop # the Salt id of your virtual machine host
|
||||
machine: quail1 # a machine name in the Vagrantfile (if not primary)
|
||||
vagrant_runas: my_username # owner of Vagrant box files on "my_laptop"
|
||||
cwd: '/home/my_username' # the path (on "my_laptop") of the Vagrantfile
|
||||
provider: my_vagrant_provider # name of entry in provider.conf file
|
||||
target_network: '10.0.0.0/8' # VM external address will be somewhere here
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
# file /etc/salt/cloud.providers.d/vagrant_provider.conf on bevymaster
|
||||
my_vagrant_provider:
|
||||
driver: vagrant
|
||||
minion:
|
||||
master: 10.124.30.7 # the hard address of the master
|
||||
|
||||
|
||||
Create and use your new Salt minion
|
||||
-----------------------------------
|
||||
|
||||
- Typing on the Salt master computer ``bevymaster``, tell it to create a new minion named ``v1`` using profile ``q1``...
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
sudo salt-cloud -p q1 v1
|
||||
sudo salt v1 network.ip_addrs
|
||||
[ you get a list of IP addresses, including the bridged one ]
|
||||
|
||||
- logged in to your laptop (or some other computer known to GitHub)...
|
||||
|
||||
\[NOTE:\] if you are using MacOS, you need to type ``ssh-add -K`` after each boot,
|
||||
unless you use one of the methods in `this gist`_.
|
||||
|
||||
.. _this gist: https://github.com/jirsbek/SSH-keys-in-macOS-Sierra-keychain
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
ssh -A vagrant@< the bridged network address >
|
||||
# [ or, if you are at /home/my_username/ on my_laptop ]
|
||||
vagrant ssh quail1
|
||||
|
||||
- then typing on your new node "v1" (a.k.a. quail1.bevy1.test)...
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
password: vagrant
|
||||
# [ stuff types out ... ]
|
||||
|
||||
ls -al /vagrant
|
||||
# [ should be shared /home/my_username from my_laptop ]
|
||||
|
||||
# you can access other network facilities using the ssh authorization
|
||||
# as recorded in your ~.ssh/ directory on my_laptop ...
|
||||
|
||||
sudo apt update
|
||||
sudo apt install git
|
||||
git clone ssh://git@github.com/yourID/your_project
|
||||
# etc...
|
||||
|
|
@ -283,6 +283,10 @@ Set up an initial profile at ``/etc/salt/cloud.profiles`` or
|
|||
thin_provision
|
||||
Specifies whether the disk should be thin provisioned or not. Default is ``thin_provision: False``.
|
||||
.. versionadded:: 2016.3.0
|
||||
eagerly_scrub
|
||||
Specifies whether the disk should be rewrite with zeros during thick provisioning or not.
|
||||
Default is ``eagerly_scrub: False``.
|
||||
.. versionadded:: Oxygen
|
||||
controller
|
||||
Specify the SCSI controller label to which this disk should be attached.
|
||||
This should be specified only when creating both the specified SCSI
|
||||
|
|
|
@ -68,8 +68,8 @@ Each salt minion establishes a connection to the master Publisher.
|
|||
EventPublisher
|
||||
--------------
|
||||
|
||||
The EventPublisher publishes events onto the event bus. It is bound to the
|
||||
following:
|
||||
The EventPublisher publishes master events out to any event listeners. It is
|
||||
bound to the following:
|
||||
|
||||
* IPC: master_event_pull.ipc
|
||||
* IPC: master_event_pub.ipc
|
||||
|
@ -110,48 +110,37 @@ The typical lifecycle of a salt job from the perspective of the master
|
|||
might be as follows:
|
||||
|
||||
1) A command is issued on the CLI. For example, 'salt my_minion test.ping'.
|
||||
|
||||
2) The 'salt' command uses LocalClient to generate a request to the salt master
|
||||
by connecting to the ReqServer on TCP:4506 and issuing the job.
|
||||
|
||||
3) The salt-master ReqServer sees the request and passes it to an available
|
||||
MWorker over workers.ipc.
|
||||
|
||||
4) A worker picks up the request and handles it. First, it checks to ensure
|
||||
that the requested user has permissions to issue the command. Then, it sends
|
||||
the publish command to all connected minions. For the curious, this happens
|
||||
in ClearFuncs.publish().
|
||||
|
||||
5) The worker announces on the master event bus that it is about to publish
|
||||
a job to connected minions. This happens by placing the event on the master
|
||||
event bus (master_event_pull.ipc) where the EventPublisher picks it up and
|
||||
distributes it to all connected event listeners on master_event_pub.ipc.
|
||||
|
||||
6) The message to the minions is encrypted and sent to the Publisher via IPC
|
||||
on publish_pull.ipc.
|
||||
|
||||
7) Connected minions have a TCP session established with the Publisher on TCP
|
||||
port 4505 where they await commands. When the Publisher receives the job over
|
||||
publish_pull, it sends the jobs across the wire to the minions for processing.
|
||||
|
||||
8) After the minions receive the request, they decrypt it and perform any
|
||||
requested work, if they determine that they are targeted to do so.
|
||||
|
||||
9) When the minion is ready to respond, it publishes the result of its job back
|
||||
to the master by sending the encrypted result back to the master on TCP 4506
|
||||
where it is again picked up by the ReqServer and forwarded to an available
|
||||
MWorker for processing. (Again, this happens by passing this message across
|
||||
workers.ipc to an available worker.)
|
||||
|
||||
10) When the MWorker receives the job it decrypts it and fires an event onto
|
||||
the master event bus (master_event_pull.ipc). (Again for the curious, this
|
||||
happens in AESFuncs._return().
|
||||
|
||||
11) The EventPublisher sees this event and re-publishes it on the bus to all
|
||||
connected listeners of the master event bus (on master_event_pub.ipc). This
|
||||
is where the LocalClient has been waiting, listening to the event bus for
|
||||
minion replies. It gathers the job and stores the result.
|
||||
|
||||
12) When all targeted minions have replied or the timeout has been exceeded,
|
||||
the salt client displays the results of the job to the user on the CLI.
|
||||
|
||||
|
@ -167,8 +156,8 @@ Salt. It can either operate as a stand-alone daemon which accepts commands
|
|||
locally via 'salt-call' or it can connect back to a master and receive commands
|
||||
remotely.
|
||||
|
||||
When starting up, salt minions connect _back_ to a master defined in the minion
|
||||
config file. The connect to two ports on the master:
|
||||
When starting up, salt minions connect *back* to a master defined in the minion
|
||||
config file. They connect to two ports on the master:
|
||||
|
||||
* TCP: 4505
|
||||
This is the connection to the master Publisher. It is on this port that
|
||||
|
@ -196,8 +185,8 @@ permissions can read or write to the bus as a common interface with the salt
|
|||
minion.
|
||||
|
||||
|
||||
Job Flow
|
||||
--------
|
||||
Minion Job Flow
|
||||
---------------
|
||||
|
||||
When a salt minion starts up, it attempts to connect to the Publisher and the
|
||||
ReqServer on the salt master. It then attempts to authenticate and once the
|
||||
|
@ -206,28 +195,22 @@ minion has successfully authenticated, it simply listens for jobs.
|
|||
Jobs normally come either come from the 'salt-call' script run by a local user
|
||||
on the salt minion or they can come directly from a master.
|
||||
|
||||
Master Job Flow
|
||||
---------------
|
||||
The job flow on a minion, coming from the master via a 'salt' command is as
|
||||
follows:
|
||||
|
||||
1) A master publishes a job that is received by a minion as outlined by the
|
||||
master's job flow above.
|
||||
|
||||
2) The minion is polling its receive socket that's connected to the master
|
||||
Publisher (TCP 4505 on master). When it detects an incoming message, it picks it
|
||||
up from the socket and decrypts it.
|
||||
|
||||
3) A new minion process or thread is created and provided with the contents of the
|
||||
decrypted message. The _thread_return() method is provided with the contents of
|
||||
the received message.
|
||||
|
||||
4) The new minion thread is created. The _thread_return() function starts up
|
||||
and actually calls out to the requested function contained in the job.
|
||||
|
||||
5) The requested function runs and returns a result. [Still in thread.]
|
||||
|
||||
6) The result of the function that's run is encrypted and returned to the
|
||||
master's ReqServer (TCP 4506 on master). [Still in thread.]
|
||||
|
||||
7) Thread exits. Because the main thread was only blocked for the time that it
|
||||
took to initialize the worker thread, many other requests could have been
|
||||
received and processed during this time.
|
||||
|
@ -241,6 +224,5 @@ clear and when they are passed using encryption. There are two rules governing
|
|||
this behaviour:
|
||||
|
||||
1) ClearFuncs is used for intra-master communication and during the initial
|
||||
authentication handshake between a minion and master during the key exhange.
|
||||
|
||||
authentication handshake between a minion and master during the key exchange.
|
||||
2) AESFuncs is used everywhere else.
|
||||
|
|
|
@ -137,11 +137,11 @@ The second return value will be a string with two possible values:
|
|||
|
||||
Both before and after the installing the target(s), you should run
|
||||
:strong:`list_pkgs` to obtain a list of the installed packages. You should then
|
||||
return the output of ``salt.utils.compare_dicts()``
|
||||
return the output of ``salt.utils.data.compare_dicts()``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
return salt.utils.compare_dicts(old, new)
|
||||
return salt.utils.data.compare_dicts(old, new)
|
||||
|
||||
|
||||
remove
|
||||
|
|
|
@ -95,19 +95,19 @@ globally available or passed in through function arguments, file data, etc.
|
|||
Mocking Loader Modules
|
||||
----------------------
|
||||
|
||||
Salt loader modules use a series of globally available dunder variables,
|
||||
``__salt__``, ``__opts__``, ``__pillar__``, etc. To facilitate testing these
|
||||
modules a mixin class was created, ``LoaderModuleMockMixin`` which can be found
|
||||
in ``tests/support/mixins.py``. The reason for the exitance of this class is
|
||||
because, historycally, and because it was easier, one would add these dunder
|
||||
variables directly on the imported module. This however, introduces unexpected
|
||||
behavior when running the full test suite since those attributes would not be
|
||||
removed once we were done testing the module and would therefor leak to other
|
||||
modules being tested with unpredictable results. This is the kind of work that
|
||||
should be defered to mock, and that's exactly what this mixin class does.
|
||||
Salt loader modules use a series of globally available dunder variables,
|
||||
``__salt__``, ``__opts__``, ``__pillar__``, etc. To facilitate testing these
|
||||
modules a mixin class was created, ``LoaderModuleMockMixin`` which can be found
|
||||
in ``tests/support/mixins.py``. The reason for the existance of this class is
|
||||
because historiclly and because it was easier, one would add these dunder
|
||||
variables directly on the imported module. This however, introduces unexpected
|
||||
behavior when running the full test suite since those attributes would not be
|
||||
removed once we were done testing the module and would therefore leak to other
|
||||
modules being tested with unpredictable results. This is the kind of work that
|
||||
should be deferred to mock, and that's exactly what this mixin class does.
|
||||
|
||||
As an example, if one needs to specify some options which should be available
|
||||
to the module being tests one should do:
|
||||
As an example, if one needs to specify some options which should be available
|
||||
to the module being tested one should do:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@ -122,8 +122,8 @@ to the module being tests one should do:
|
|||
}
|
||||
}
|
||||
|
||||
Consider this more extensive example from
|
||||
``tests/unit/modules/test_libcloud_dns.py``::
|
||||
Consider this more extensive example from
|
||||
``tests/unit/modules/test_libcloud_dns.py``:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
@ -173,10 +173,10 @@ Consider this more extensive example from
|
|||
return {libcloud_dns: module_globals}
|
||||
|
||||
|
||||
What happens on the above example is that, we mock a call to
|
||||
`__salt__['config.option']` to return the configuration needed for the
|
||||
execution of the tests. Additionally, if the ``libcloud`` library is not
|
||||
available, since that's not actually part of whats being tested, we mocked that
|
||||
What happens in the above example is we mock a call to
|
||||
`__salt__['config.option']` to return the configuration needed for the
|
||||
execution of the tests. Additionally, if the ``libcloud`` library is not
|
||||
available, since that's not actually part of what's being tested, we mocked that
|
||||
import by patching ``sys.modules`` when tests are running.
|
||||
|
||||
|
||||
|
@ -245,7 +245,7 @@ To understand how one might integrate Mock into writing a unit test for Salt,
|
|||
let's imagine a scenario in which we're testing an execution module that's
|
||||
designed to operate on a database. Furthermore, let's imagine two separate
|
||||
methods, here presented in pseduo-code in an imaginary execution module called
|
||||
'db.py.
|
||||
'db.py'.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
|
|
@ -246,6 +246,7 @@ Server configuration values and their defaults:
|
|||
|
||||
# Bind to LDAP anonymously to determine group membership
|
||||
# Active Directory does not allow anonymous binds without special configuration
|
||||
# In addition, if auth.ldap.anonymous is True, empty bind passwords are not permitted.
|
||||
auth.ldap.anonymous: False
|
||||
|
||||
# FOR TESTING ONLY, this is a VERY insecure setting.
|
||||
|
@ -285,7 +286,11 @@ and groups, it re-authenticates as the user running the Salt commands.
|
|||
|
||||
If you are already aware of the structure of your DNs and permissions in your LDAP store are set such that
|
||||
users can look up their own group memberships, then the first and second users can be the same. To tell Salt this is
|
||||
the case, omit the ``auth.ldap.bindpw`` parameter. You can template the ``binddn`` like this:
|
||||
the case, omit the ``auth.ldap.bindpw`` parameter. Note this is not the same thing as using an anonymous bind.
|
||||
Most LDAP servers will not permit anonymous bind, and as mentioned above, if `auth.ldap.anonymous` is False you
|
||||
cannot use an empty password.
|
||||
|
||||
You can template the ``binddn`` like this:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
|
|
|
@ -4,12 +4,25 @@ Event System
|
|||
|
||||
The Salt Event System is used to fire off events enabling third party
|
||||
applications or external processes to react to behavior within Salt.
|
||||
The event system uses a publish-subscribe pattern, otherwise know as pub/sub.
|
||||
|
||||
The event system is comprised of a two primary components:
|
||||
Event Bus
|
||||
=========
|
||||
|
||||
The event system is comprised of a two primary components, which make up the
|
||||
concept of an Event Bus:
|
||||
|
||||
* The event sockets which publishes events.
|
||||
* The event library which can listen to events and send events into the salt system.
|
||||
|
||||
Events are published onto the event bus and event bus subscribers listen for the
|
||||
published events.
|
||||
|
||||
The event bus is used for both inter-process communication as well as network transport
|
||||
in Salt. Inter-process communication is provided through UNIX domain sockets (UDX).
|
||||
|
||||
The Salt Master and each Salt Minion has their own event bus.
|
||||
|
||||
Event types
|
||||
===========
|
||||
|
||||
|
@ -21,7 +34,7 @@ Event types
|
|||
Listening for Events
|
||||
====================
|
||||
|
||||
Salt's Event Bus is used heavily within Salt and it is also written to
|
||||
Salt's event system is used heavily within Salt and it is also written to
|
||||
integrate heavily with existing tooling and scripts. There is a variety of
|
||||
ways to consume it.
|
||||
|
||||
|
|
|
@ -45,11 +45,27 @@ but leave any existing config, cache, and PKI information.
|
|||
Salt Minion Installation
|
||||
========================
|
||||
|
||||
If the system is missing the appropriate version of the Visual C++
|
||||
Redistributable (vcredist) the user will be prompted to install it. Click ``OK``
|
||||
to install the vcredist. Click ``Cancel`` to abort the installation without
|
||||
making modifications to the system.
|
||||
|
||||
If Salt is already installed on the system the user will be prompted to remove
|
||||
the previous installation. Click ``OK`` to uninstall Salt without removing the
|
||||
configuration, PKI information, or cached files. Click ``Cancel`` to abort the
|
||||
installation before making any modifications to the system.
|
||||
|
||||
After the Welcome and the License Agreement, the installer asks for two bits of
|
||||
information to configure the minion; the master hostname and the minion name.
|
||||
The installer will update the minion config with these options. If the installer
|
||||
finds an existing minion config file, these fields will be populated with values
|
||||
from the existing config.
|
||||
The installer will update the minion config with these options.
|
||||
|
||||
If the installer finds an existing minion config file, these fields will be
|
||||
populated with values from the existing config, but they will be grayed out.
|
||||
There will also be a checkbox to use the existing config. If you continue, the
|
||||
existing config will be used. If the checkbox is unchecked, default values are
|
||||
displayed and can be changed. If you continue, the existing config file in
|
||||
``c:\salt\conf`` will be removed along with the ``c:\salt\conf\minion.d`
|
||||
directory. The values entered will be used with the default config.
|
||||
|
||||
The final page allows you to start the minion service and optionally change its
|
||||
startup type. By default, the minion is set to ``Automatic``. You can change the
|
||||
|
@ -71,11 +87,6 @@ be managed there or from the command line like any other Windows service.
|
|||
sc start salt-minion
|
||||
net start salt-minion
|
||||
|
||||
.. note::
|
||||
If the minion won't start, you may need to install the Microsoft Visual C++
|
||||
2008 x64 SP1 redistributable. Allow all Windows updates to run salt-minion
|
||||
smoothly.
|
||||
|
||||
Installation Prerequisites
|
||||
--------------------------
|
||||
|
||||
|
@ -96,15 +107,29 @@ Minion silently:
|
|||
========================= =====================================================
|
||||
Option Description
|
||||
========================= =====================================================
|
||||
``/minion-name=`` A string value to set the minion name. Default is
|
||||
'hostname'
|
||||
``/master=`` A string value to set the IP address or host name of
|
||||
the master. Default value is 'salt'
|
||||
the master. Default value is 'salt'. You can pass a
|
||||
single master or a comma-separated list of masters.
|
||||
Setting the master will replace existing config with
|
||||
the default config. Cannot be used in conjunction
|
||||
with ``/use-existing-config``
|
||||
``/minion-name=`` A string value to set the minion name. Default is
|
||||
'hostname'. Setting the minion name will replace
|
||||
existing config with the default config. Cannot be
|
||||
used in conjunction with ``/use-existing-config``
|
||||
``/start-minion=`` Either a 1 or 0. '1' will start the salt-minion
|
||||
service, '0' will not. Default is to start the
|
||||
service after installation.
|
||||
service after installation
|
||||
``/start-minion-delayed`` Set the minion start type to
|
||||
``Automatic (Delayed Start)``
|
||||
``/use-existing-config`` Either a 1 or 0. '1' will use the existing config if
|
||||
present. '0' will replace existing config with the
|
||||
default config. Default is '1'. If this is set to '1'
|
||||
values passed in ``/master`` and ``/minion-name``
|
||||
will be ignored
|
||||
``/S`` Runs the installation silently. Uses the above
|
||||
settings or the defaults
|
||||
``/?`` Displays command line help
|
||||
========================= =====================================================
|
||||
|
||||
.. note::
|
||||
|
|
|
@ -1727,7 +1727,7 @@ in the current Jinja context.
|
|||
|
||||
.. code-block:: jinja
|
||||
|
||||
Context is: {{ show_full_context() }}
|
||||
Context is: {{ show_full_context()|yaml(False) }}
|
||||
|
||||
.. jinja_ref:: logs
|
||||
|
||||
|
|
|
@ -4,9 +4,21 @@ Salt 2016.11.8 Release Notes
|
|||
|
||||
Version 2016.11.8 is a bugfix release for :ref:`2016.11.0 <release-2016-11-0>`.]
|
||||
|
||||
Anonymous Binds and LDAP/Active Directory
|
||||
-----------------------------------------
|
||||
|
||||
When auth.ldap.anonymous is set to False, the bind password can no longer be empty.
|
||||
|
||||
Changes for v2016.11.7..v2016.11.8
|
||||
----------------------------------
|
||||
|
||||
Security Fix
|
||||
============
|
||||
|
||||
CVE-2017-14695 Directory traversal vulnerability in minion id validation in SaltStack. Allows remote minions with incorrect credentials to authenticate to a master via a crafted minion ID. Credit for discovering the security flaw goes to: Julian Brost (julian@0x4a42.net)
|
||||
|
||||
CVE-2017-14696 Remote Denial of Service with a specially crafted authentication request. Credit for discovering the security flaw goes to: Julian Brost (julian@0x4a42.net)
|
||||
|
||||
Extended changelog courtesy of Todd Stansell (https://github.com/tjstansell/salt-changelogs):
|
||||
|
||||
*Generated at: 2017-09-11T14:52:27Z*
|
||||
|
|
6
doc/topics/releases/2016.11.9.rst
Normal file
6
doc/topics/releases/2016.11.9.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
============================
|
||||
Salt 2016.11.9 Release Notes
|
||||
============================
|
||||
|
||||
Version 2016.11.9 is a bugfix release for :ref:`2016.11.0 <release-2016-11-0>`.]
|
||||
|
|
@ -7,23 +7,9 @@ Version 2016.3.8 is a bugfix release for :ref:`2016.3.0 <release-2016-3-0>`.
|
|||
Changes for v2016.3.7..v2016.3.8
|
||||
--------------------------------
|
||||
|
||||
New master configuration option `allow_minion_key_revoke`, defaults to True. This option
|
||||
controls whether a minion can request that the master revoke its key. When True, a minion
|
||||
can request a key revocation and the master will comply. If it is False, the key will not
|
||||
be revoked by the msater.
|
||||
Security Fix
|
||||
============
|
||||
|
||||
New master configuration option `require_minion_sign_messages`
|
||||
This requires that minions cryptographically sign the messages they
|
||||
publish to the master. If minions are not signing, then log this information
|
||||
at loglevel 'INFO' and drop the message without acting on it.
|
||||
CVE-2017-14695 Directory traversal vulnerability in minion id validation in SaltStack. Allows remote minions with incorrect credentials to authenticate to a master via a crafted minion ID. Credit for discovering the security flaw goes to: Julian Brost (julian@0x4a42.net)
|
||||
|
||||
New master configuration option `drop_messages_signature_fail`
|
||||
Drop messages from minions when their signatures do not validate.
|
||||
Note that when this option is False but `require_minion_sign_messages` is True
|
||||
minions MUST sign their messages but the validity of their signatures
|
||||
is ignored.
|
||||
|
||||
New minion configuration option `minion_sign_messages`
|
||||
Causes the minion to cryptographically sign the payload of messages it places
|
||||
on the event bus for the master. The payloads are signed with the minion's
|
||||
private key so the master can verify the signature with its public key.
|
||||
CVE-2017-14696 Remote Denial of Service with a specially crafted authentication request. Credit for discovering the security flaw goes to: Julian Brost (julian@0x4a42.net)
|
||||
|
|
29
doc/topics/releases/2016.3.9.rst
Normal file
29
doc/topics/releases/2016.3.9.rst
Normal file
|
@ -0,0 +1,29 @@
|
|||
===========================
|
||||
Salt 2016.3.9 Release Notes
|
||||
===========================
|
||||
|
||||
Version 2016.3.9 is a bugfix release for :ref:`2016.3.0 <release-2016-3-0>`.
|
||||
|
||||
Changes for v2016.3.7..v2016.3.9
|
||||
--------------------------------
|
||||
|
||||
New master configuration option `allow_minion_key_revoke`, defaults to True. This option
|
||||
controls whether a minion can request that the master revoke its key. When True, a minion
|
||||
can request a key revocation and the master will comply. If it is False, the key will not
|
||||
be revoked by the msater.
|
||||
|
||||
New master configuration option `require_minion_sign_messages`
|
||||
This requires that minions cryptographically sign the messages they
|
||||
publish to the master. If minions are not signing, then log this information
|
||||
at loglevel 'INFO' and drop the message without acting on it.
|
||||
|
||||
New master configuration option `drop_messages_signature_fail`
|
||||
Drop messages from minions when their signatures do not validate.
|
||||
Note that when this option is False but `require_minion_sign_messages` is True
|
||||
minions MUST sign their messages but the validity of their signatures
|
||||
is ignored.
|
||||
|
||||
New minion configuration option `minion_sign_messages`
|
||||
Causes the minion to cryptographically sign the payload of messages it places
|
||||
on the event bus for the master. The payloads are signed with the minion's
|
||||
private key so the master can verify the signature with its public key.
|
|
@ -7,18 +7,40 @@ Version 2017.7.2 is a bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
|
|||
Changes for v2017.7.1..v2017.7.2
|
||||
--------------------------------
|
||||
|
||||
Security Fix
|
||||
============
|
||||
|
||||
CVE-2017-14695 Directory traversal vulnerability in minion id validation in SaltStack. Allows remote minions with incorrect credentials to authenticate to a master via a crafted minion ID. Credit for discovering the security flaw goes to: Julian Brost (julian@0x4a42.net)
|
||||
|
||||
CVE-2017-14696 Remote Denial of Service with a specially crafted authentication request. Credit for discovering the security flaw goes to: Julian Brost (julian@0x4a42.net)
|
||||
|
||||
Known Issues
|
||||
============
|
||||
|
||||
On 2017.7.2 when using salt-api and cherrypy version 5.6.0, issue `#43581`_ will occur when starting the salt-api service. We have patched the cherry-py packages for python-cherrypy-5.6.0-2 from repo.saltstack.com. If you are using python-cherrypy-5.6.0-1 please ensure to run `yum install python-cherrypy` to install the new patched version.
|
||||
|
||||
Extended changelog courtesy of Todd Stansell (https://github.com/tjstansell/salt-changelogs):
|
||||
|
||||
*Generated at: 2017-09-26T21:06:19Z*
|
||||
*Generated at: 2017-10-02T21:10:14Z*
|
||||
|
||||
Statistics:
|
||||
Statistics
|
||||
==========
|
||||
|
||||
- Total Merges: **326**
|
||||
- Total Issue references: **133**
|
||||
- Total PR references: **389**
|
||||
- Total Merges: **328**
|
||||
- Total Issue references: **134**
|
||||
- Total PR references: **391**
|
||||
|
||||
Changes:
|
||||
Changes
|
||||
=======
|
||||
|
||||
- **PR** `#43868`_: (*rallytime*) Back-port `#43847`_ to 2017.7.2
|
||||
* Fix to module.run
|
||||
|
||||
- **PR** `#43756`_: (*gtmanfred*) split build and install for pkg osx
|
||||
@ *2017-09-26T20:51:28Z*
|
||||
|
||||
* 88414d5 Merge pull request `#43756`_ from gtmanfred/2017.7.2
|
||||
* f7df41f split build and install for pkg osx
|
||||
|
||||
- **PR** `#43585`_: (*rallytime*) Back-port `#43330`_ to 2017.7.2
|
||||
@ *2017-09-19T17:33:34Z*
|
||||
|
@ -3097,6 +3119,13 @@ Changes:
|
|||
.. _`#475`: https://github.com/saltstack/salt/issues/475
|
||||
.. _`#480`: https://github.com/saltstack/salt/issues/480
|
||||
.. _`#495`: https://github.com/saltstack/salt/issues/495
|
||||
.. _`#43581`: https://github.com/saltstack/salt/issues/43581
|
||||
.. _`#43756`: https://github.com/saltstack/salt/pull/43756
|
||||
.. _`#43847`: https://github.com/saltstack/salt/pull/43847
|
||||
.. _`#43868`: https://github.com/saltstack/salt/pull/43868
|
||||
.. _`#475`: https://github.com/saltstack/salt/issues/475
|
||||
.. _`#480`: https://github.com/saltstack/salt/issues/480
|
||||
.. _`#495`: https://github.com/saltstack/salt/issues/495
|
||||
.. _`bp-37424`: https://github.com/saltstack/salt/pull/37424
|
||||
.. _`bp-39366`: https://github.com/saltstack/salt/pull/39366
|
||||
.. _`bp-41543`: https://github.com/saltstack/salt/pull/41543
|
||||
|
|
6
doc/topics/releases/2017.7.3.rst
Normal file
6
doc/topics/releases/2017.7.3.rst
Normal file
|
@ -0,0 +1,6 @@
|
|||
============================
|
||||
Salt 2017.7.3 Release Notes
|
||||
============================
|
||||
|
||||
Version 2017.7.3 is a bugfix release for :ref:`2017.7.0 <release-2017-7-0>`.
|
||||
|
|
@ -55,6 +55,13 @@ The new grains added are:
|
|||
|
||||
* ``fc_wwn``: Show all fibre channel world wide port names for a host
|
||||
* ``iscsi_iqn``: Show the iSCSI IQN name for a host
|
||||
* ``swap_total``: Show the configured swap_total for Linux, *BSD, OS X and Solaris/SunOS
|
||||
|
||||
Grains Changes
|
||||
--------------
|
||||
|
||||
* The ``virtual`` grain identifies reports KVM and VMM hypervisors when running
|
||||
an OpenBSD guest
|
||||
|
||||
New Modules
|
||||
-----------
|
||||
|
@ -110,6 +117,31 @@ The ``state_output`` parameter now supports ``full_id``, ``changes_id`` and ``te
|
|||
Just like ``mixed_id``, these use the state ID as name in the highstate output.
|
||||
For more information on these output modes, see the docs for the :mod:`Highstate Outputter <salt.output.highstate>`.
|
||||
|
||||
Windows Installer: Changes to existing config handling
|
||||
------------------------------------------------------
|
||||
Behavior with existing configuration has changed. With previous installers the
|
||||
existing config was used and the master and minion id could be modified via the
|
||||
installer. It was problematic in that it didn't account for configuration that
|
||||
may be defined in the ``minion.d`` directory. This change gives you the option
|
||||
via a checkbox to either use the existing config with out changes or the default
|
||||
config using values you pass to the installer. If you choose to use the existing
|
||||
config then no changes are made. If not, the existing config is deleted, to
|
||||
include the ``minion.d`` directory, and the default config is used. A
|
||||
command-line switch (``/use-existing-config``) has also been added to control
|
||||
this behavior.
|
||||
|
||||
Windows Installer: Multi-master configuration
|
||||
---------------------------------------------
|
||||
The installer now has the ability to apply a multi-master configuration either
|
||||
from the gui or the command line. The ``master`` field in the gui can accept
|
||||
either a single master or a comma-separated list of masters. The command-line
|
||||
switch (``/master=``) can accept the same.
|
||||
|
||||
Windows Installer: Command-line help
|
||||
------------------------------------
|
||||
The Windows installer will now display command-line help when a help switch
|
||||
(``/?``) is passed.
|
||||
|
||||
Salt Cloud Features
|
||||
-------------------
|
||||
|
||||
|
@ -132,6 +164,58 @@ file. For example:
|
|||
|
||||
These commands will run in sequence **before** the bootstrap script is executed.
|
||||
|
||||
New salt-cloud Grains
|
||||
=====================
|
||||
|
||||
When salt cloud creates a new minon, it will now add grain information
|
||||
to the minion configuration file, identifying the resources originally used
|
||||
to create it.
|
||||
|
||||
The generated grain information will appear similar to:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
grains:
|
||||
salt-cloud:
|
||||
driver: ec2
|
||||
provider: my_ec2:ec2
|
||||
profile: ec2-web
|
||||
|
||||
The generation of salt-cloud grains can be surpressed by the
|
||||
option ``enable_cloud_grains: 'False'`` in the cloud configuration file.
|
||||
|
||||
Upgraded Saltify Driver
|
||||
=======================
|
||||
|
||||
The salt-cloud Saltify driver is used to provision machines which
|
||||
are not controlled by a dedicated cloud supervisor (such as typical hardware
|
||||
machines) by pushing a salt-bootstrap command to them and accepting them on
|
||||
the salt master. Creation of a node has been its only function and no other
|
||||
salt-cloud commands were implemented.
|
||||
|
||||
With this upgrade, it can use the salt-api to provide advanced control,
|
||||
such as rebooting a machine, querying it along with conventional cloud minions,
|
||||
and, ultimately, disconnecting it from its master.
|
||||
|
||||
After disconnection from ("destroying" on) one master, a machine can be
|
||||
re-purposed by connecting to ("creating" on) a subsequent master.
|
||||
|
||||
New Vagrant Driver
|
||||
==================
|
||||
|
||||
The salt-cloud Vagrant driver brings virtual machines running in a limited
|
||||
environment, such as a programmer's workstation, under salt-cloud control.
|
||||
This can be useful for experimentation, instruction, or testing salt configurations.
|
||||
|
||||
Using salt-api on the master, and a salt-minion running on the host computer,
|
||||
the Vagrant driver can create (``vagrant up``), restart (``vagrant reload``),
|
||||
and destroy (``vagrant destroy``) VMs, as controlled by salt-cloud profiles
|
||||
which designate a ``Vagrantfile`` on the host machine.
|
||||
|
||||
The master can be a very limited machine, such as a Raspberry Pi, or a small
|
||||
VagrantBox VM.
|
||||
|
||||
|
||||
New pillar/master_tops module called saltclass
|
||||
----------------------------------------------
|
||||
|
||||
|
@ -329,7 +413,7 @@ signed certificates. :ref:`Here<new-pywinrm>` for more information.
|
|||
DigitalOcean
|
||||
------------
|
||||
|
||||
The DigitalOcean driver has been renamed to conform to the companies name. The
|
||||
The DigitalOcean driver has been renamed to conform to the company name. The
|
||||
new driver name is ``digitalocean``. The old name ``digital_ocean`` and a
|
||||
short one ``do`` will still be supported through virtual aliases, this is mostly
|
||||
cosmetic.
|
||||
|
@ -338,7 +422,7 @@ Solaris Logical Domains In Virtual Grain
|
|||
----------------------------------------
|
||||
|
||||
Support has been added to the ``virtual`` grain for detecting Solaris LDOMs
|
||||
running on T-Series SPARC hardware. The ``virtual_subtype`` grain is
|
||||
running on T-Series SPARC hardware. The ``virtual_subtype`` grain is
|
||||
populated as a list of domain roles.
|
||||
|
||||
Lists of comments in state returns
|
||||
|
@ -353,7 +437,7 @@ Beacon configuration changes
|
|||
|
||||
In order to remain consistent and to align with other Salt components such as states,
|
||||
support for configuring beacons using dictionary based configuration has been deprecated
|
||||
in favor of list based configuration. All beacons have a validation function which will
|
||||
in favor of list based configuration. All beacons have a validation function which will
|
||||
check the configuration for the correct format and only load if the validation passes.
|
||||
|
||||
- ``avahi_announce`` beacon
|
||||
|
@ -1014,3 +1098,10 @@ The ``version.py`` file had the following changes:
|
|||
Warnings for moving away from the ``env`` option were removed. ``saltenv`` should be
|
||||
used instead. The removal of these warnings does not have a behavior change. Only
|
||||
the warning text was removed.
|
||||
|
||||
Sentry Log Handler
|
||||
------------------
|
||||
|
||||
Configuring sentry raven python client via ``project``, ``servers``, ``public_key
|
||||
and ``secret_key`` is deprecated and won't work with sentry clients > 3.0.
|
||||
Instead, the ``dsn`` config param must be used.
|
||||
|
|
|
@ -29,6 +29,7 @@ the name of the repository, and the link to the repository:
|
|||
For HTTP/HTTPS Basic authorization you can define credentials:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
my_repo:
|
||||
url: https://spm.example.com/
|
||||
username: user
|
||||
|
|
|
@ -164,7 +164,7 @@ states are evaluated before ``tgt`` states.
|
|||
Each of these sections needs to be evaluated as text, rather than as YAML.
|
||||
Consider the following block:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: text
|
||||
|
||||
pre_local_state: >
|
||||
echo test > /tmp/spmtest:
|
||||
|
@ -187,7 +187,7 @@ a minion.
|
|||
the ``>`` marker to denote that the state is evaluated as text, not a data
|
||||
structure.
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: text
|
||||
|
||||
pre_local_state: >
|
||||
echo test > /tmp/spmtest:
|
||||
|
@ -203,7 +203,7 @@ the ``spm`` command is running on is a master.
|
|||
Because ``tgt`` states require that a target be specified, their code blocks
|
||||
are a little different. Consider the following state:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: text
|
||||
|
||||
pre_tgt_state:
|
||||
tgt: '*'
|
||||
|
@ -229,7 +229,7 @@ This means that you can use Jinja or any other supported renderer inside of
|
|||
Salt. All formula variables are available to the renderer, so you can reference
|
||||
``FORMULA`` data inside your state if you need to:
|
||||
|
||||
.. code-block::
|
||||
.. code-block:: text
|
||||
|
||||
pre_tgt_state:
|
||||
tgt: '*'
|
||||
|
|
|
@ -34,7 +34,7 @@ passing on a single socket.
|
|||
TLS Support
|
||||
===========
|
||||
|
||||
.. version_added:: 2016.11.1
|
||||
.. versionadded:: 2016.11.1
|
||||
|
||||
The TCP transport allows for the master/minion communication to be optionally
|
||||
wrapped in a TLS connection. Enabling this is simple, the master and minion need
|
||||
|
|
|
@ -141,7 +141,7 @@ If the master seems to be unresponsive, a SIGUSR1 can be passed to the
|
|||
salt-master threads to display what piece of code is executing. This debug
|
||||
information can be invaluable in tracking down bugs.
|
||||
|
||||
To pass a SIGUSR1 to the master, first make sure the minion is running in the
|
||||
To pass a SIGUSR1 to the master, first make sure the master is running in the
|
||||
foreground. Stop the service if it is running as a daemon, and start it in the
|
||||
foreground like so:
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@ Installing Dependencies
|
|||
=======================
|
||||
|
||||
Both pygit2_ and GitPython_ are supported Python interfaces to git. If
|
||||
compatible versions of both are installed, pygit2_ will preferred. In these
|
||||
compatible versions of both are installed, pygit2_ will be preferred. In these
|
||||
cases, GitPython_ can be forced using the :conf_master:`gitfs_provider`
|
||||
parameter in the master config file.
|
||||
|
||||
|
|
|
@ -33,3 +33,5 @@ Tutorials Index
|
|||
* :ref:`SaltStack Walk-through <tutorial-salt-walk-through>`
|
||||
* :ref:`Writing Salt Tests <tutorial-salt-testing>`
|
||||
* :ref:`Multi-cloud orchestration with Apache Libcloud <tutorial-libcloud>`
|
||||
* :ref:`Running Salt States and Commands in Docker Containers <docker-sls>`
|
||||
* :ref:`Preseed Minion with Accepted Key <tutorial-preseed-key>`
|
||||
|
|
|
@ -260,14 +260,11 @@ the retention time defined by
|
|||
|
||||
250 jobs/day * 2000 minions returns = 500,000 files a day
|
||||
|
||||
If no job history is needed, the job cache can be disabled:
|
||||
Use and External Job Cache
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
job_cache: False
|
||||
|
||||
|
||||
If the job cache is necessary there are (currently) 2 options:
|
||||
An external job cache allows for job storage to be placed on an external
|
||||
system, such as a database.
|
||||
|
||||
- ext_job_cache: this will have the minions store their return data directly
|
||||
into a returner (not sent through the Master)
|
||||
|
@ -287,3 +284,20 @@ for up to sixty seconds by default.
|
|||
|
||||
To enable the master key cache, set `key_cache: 'sched'` in the master
|
||||
configuration file.
|
||||
|
||||
Disable The Job Cache
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
The job cache is a central component of the Salt Master and many aspects of
|
||||
the Salt Master will not function correctly without a running job cache.
|
||||
|
||||
Disabling the job cache is **STRONGLY DISCOURAGED** and should not be done
|
||||
unless the master is being used to execute routines that require no history
|
||||
or reliable feedback!
|
||||
|
||||
The job cache can be disabled:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
job_cache: False
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@ Supported Operating Systems
|
|||
.. note::
|
||||
|
||||
In the event you do not see your distribution or version available please
|
||||
review the develop branch on GitHub as it main contain updates that are
|
||||
review the develop branch on GitHub as it may contain updates that are
|
||||
not present in the stable release:
|
||||
https://github.com/saltstack/salt-bootstrap/tree/develop
|
||||
|
||||
|
|
|
@ -88,7 +88,8 @@ sudo $PKGRESOURCES/build_env.sh $PYVER
|
|||
echo -n -e "\033]0;Build: Install Salt\007"
|
||||
sudo rm -rf $SRCDIR/build
|
||||
sudo rm -rf $SRCDIR/dist
|
||||
sudo $PYTHON $SRCDIR/setup.py build -e "$PYTHON -E -s" install
|
||||
sudo $PYTHON $SRCDIR/setup.py build -e "$PYTHON -E -s"
|
||||
sudo $PYTHON $SRCDIR/setup.py install
|
||||
|
||||
############################################################################
|
||||
# Build Package
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
!define PRODUCT_UNINST_KEY "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME}"
|
||||
!define PRODUCT_UNINST_KEY_OTHER "Software\Microsoft\Windows\CurrentVersion\Uninstall\${PRODUCT_NAME_OTHER}"
|
||||
!define PRODUCT_UNINST_ROOT_KEY "HKLM"
|
||||
!define OUTFILE "Salt-Minion-${PRODUCT_VERSION}-Py${PYTHON_VERSION}-${CPUARCH}-Setup.exe"
|
||||
|
||||
# Import Libraries
|
||||
!include "MUI2.nsh"
|
||||
|
@ -52,6 +53,15 @@ ${StrStrAdv}
|
|||
Pop "${ResultVar}"
|
||||
!macroend
|
||||
|
||||
# Part of the Explode function for Strings
|
||||
!define Explode "!insertmacro Explode"
|
||||
!macro Explode Length Separator String
|
||||
Push `${Separator}`
|
||||
Push `${String}`
|
||||
Call Explode
|
||||
Pop `${Length}`
|
||||
!macroend
|
||||
|
||||
|
||||
###############################################################################
|
||||
# Configure Pages, Ordering, and Configuration
|
||||
|
@ -92,10 +102,17 @@ Var Dialog
|
|||
Var Label
|
||||
Var CheckBox_Minion_Start
|
||||
Var CheckBox_Minion_Start_Delayed
|
||||
Var ConfigMasterHost
|
||||
Var MasterHost
|
||||
Var MasterHost_State
|
||||
Var ConfigMinionName
|
||||
Var MinionName
|
||||
Var MinionName_State
|
||||
Var ExistingConfigFound
|
||||
Var UseExistingConfig
|
||||
Var UseExistingConfig_State
|
||||
Var WarningExistingConfig
|
||||
Var WarningDefaultConfig
|
||||
Var StartMinion
|
||||
Var StartMinionDelayed
|
||||
Var DeleteInstallDir
|
||||
|
@ -115,27 +132,105 @@ Function pageMinionConfig
|
|||
Abort
|
||||
${EndIf}
|
||||
|
||||
# Master IP or Hostname Dialog Control
|
||||
${NSD_CreateLabel} 0 0 100% 12u "Master IP or Hostname:"
|
||||
Pop $Label
|
||||
|
||||
${NSD_CreateText} 0 13u 100% 12u $MasterHost_State
|
||||
Pop $MasterHost
|
||||
|
||||
# Minion ID Dialog Control
|
||||
${NSD_CreateLabel} 0 30u 100% 12u "Minion Name:"
|
||||
Pop $Label
|
||||
|
||||
${NSD_CreateText} 0 43u 100% 12u $MinionName_State
|
||||
Pop $MinionName
|
||||
|
||||
# Use Existing Config Checkbox
|
||||
${NSD_CreateCheckBox} 0 65u 100% 12u "&Use Existing Config"
|
||||
Pop $UseExistingConfig
|
||||
${NSD_OnClick} $UseExistingConfig pageMinionConfig_OnClick
|
||||
|
||||
# Add Existing Config Warning Label
|
||||
${NSD_CreateLabel} 0 80u 100% 60u "The values above are taken from an \
|
||||
existing configuration found in `c:\salt\conf\minion`. Configuration \
|
||||
settings defined in the `minion.d` directories, if they exist, are not \
|
||||
shown here.$\r$\n\
|
||||
$\r$\n\
|
||||
Clicking `Install` will leave the existing config unchanged."
|
||||
Pop $WarningExistingConfig
|
||||
CreateFont $0 "Arial" 10 500 /ITALIC
|
||||
SendMessage $WarningExistingConfig ${WM_SETFONT} $0 1
|
||||
SetCtlColors $WarningExistingConfig 0xBB0000 transparent
|
||||
|
||||
# Add Default Config Warning Label
|
||||
${NSD_CreateLabel} 0 80u 100% 60u "Clicking `Install` will remove the \
|
||||
the existing minion config file and remove the minion.d directories. \
|
||||
The values above will be used in the new default config."
|
||||
Pop $WarningDefaultConfig
|
||||
CreateFont $0 "Arial" 10 500 /ITALIC
|
||||
SendMessage $WarningDefaultConfig ${WM_SETFONT} $0 1
|
||||
SetCtlColors $WarningDefaultConfig 0xBB0000 transparent
|
||||
|
||||
# If no existing config found, disable the checkbox and stuff
|
||||
# Set UseExistingConfig_State to 0
|
||||
${If} $ExistingConfigFound == 0
|
||||
StrCpy $UseExistingConfig_State 0
|
||||
ShowWindow $UseExistingConfig ${SW_HIDE}
|
||||
ShowWindow $WarningExistingConfig ${SW_HIDE}
|
||||
ShowWindow $WarningDefaultConfig ${SW_HIDE}
|
||||
${Endif}
|
||||
|
||||
${NSD_SetState} $UseExistingConfig $UseExistingConfig_State
|
||||
|
||||
Call pageMinionConfig_OnClick
|
||||
|
||||
nsDialogs::Show
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function pageMinionConfig_OnClick
|
||||
|
||||
# You have to pop the top handle to keep the stack clean
|
||||
Pop $R0
|
||||
|
||||
# Assign the current checkbox state to the variable
|
||||
${NSD_GetState} $UseExistingConfig $UseExistingConfig_State
|
||||
|
||||
# Validate the checkboxes
|
||||
${If} $UseExistingConfig_State == ${BST_CHECKED}
|
||||
# Use Existing Config is checked, show warning
|
||||
ShowWindow $WarningExistingConfig ${SW_SHOW}
|
||||
EnableWindow $MasterHost 0
|
||||
EnableWindow $MinionName 0
|
||||
${NSD_SetText} $MasterHost $ConfigMasterHost
|
||||
${NSD_SetText} $MinionName $ConfigMinionName
|
||||
${If} $ExistingConfigFound == 1
|
||||
ShowWindow $WarningDefaultConfig ${SW_HIDE}
|
||||
${Endif}
|
||||
${Else}
|
||||
# Use Existing Config is not checked, hide the warning
|
||||
ShowWindow $WarningExistingConfig ${SW_HIDE}
|
||||
EnableWindow $MasterHost 1
|
||||
EnableWindow $MinionName 1
|
||||
${NSD_SetText} $MasterHost $MasterHost_State
|
||||
${NSD_SetText} $MinionName $MinionName_State
|
||||
${If} $ExistingConfigFound == 1
|
||||
ShowWindow $WarningDefaultConfig ${SW_SHOW}
|
||||
${Endif}
|
||||
${EndIf}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function pageMinionConfig_Leave
|
||||
|
||||
${NSD_GetText} $MasterHost $MasterHost_State
|
||||
${NSD_GetText} $MinionName $MinionName_State
|
||||
${NSD_GetState} $UseExistingConfig $UseExistingConfig_State
|
||||
|
||||
Call RemoveExistingConfig
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
@ -194,7 +289,7 @@ FunctionEnd
|
|||
!else
|
||||
Name "${PRODUCT_NAME} ${PRODUCT_VERSION}"
|
||||
!endif
|
||||
OutFile "Salt-Minion-${PRODUCT_VERSION}-Py${PYTHON_VERSION}-${CPUARCH}-Setup.exe"
|
||||
OutFile "${OutFile}"
|
||||
InstallDir "c:\salt"
|
||||
InstallDirRegKey HKLM "${PRODUCT_DIR_REGKEY}" ""
|
||||
ShowInstDetails show
|
||||
|
@ -311,8 +406,6 @@ SectionEnd
|
|||
|
||||
Function .onInit
|
||||
|
||||
Call getMinionConfig
|
||||
|
||||
Call parseCommandLineSwitches
|
||||
|
||||
# Check for existing installation
|
||||
|
@ -364,6 +457,23 @@ Function .onInit
|
|||
|
||||
skipUninstall:
|
||||
|
||||
Call getMinionConfig
|
||||
|
||||
IfSilent 0 +2
|
||||
Call RemoveExistingConfig
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
Function RemoveExistingConfig
|
||||
|
||||
${If} $ExistingConfigFound == 1
|
||||
${AndIf} $UseExistingConfig_State == 0
|
||||
# Wipe out the Existing Config
|
||||
Delete "$INSTDIR\conf\minion"
|
||||
RMDir /r "$INSTDIR\conf\minion.d"
|
||||
${EndIf}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
@ -407,7 +517,9 @@ Section -Post
|
|||
nsExec::Exec "nssm.exe set salt-minion AppStopMethodConsole 24000"
|
||||
nsExec::Exec "nssm.exe set salt-minion AppStopMethodWindow 2000"
|
||||
|
||||
Call updateMinionConfig
|
||||
${If} $UseExistingConfig_State == 0
|
||||
Call updateMinionConfig
|
||||
${EndIf}
|
||||
|
||||
Push "C:\salt"
|
||||
Call AddToPath
|
||||
|
@ -534,18 +646,32 @@ FunctionEnd
|
|||
# Helper Functions
|
||||
###############################################################################
|
||||
Function MsiQueryProductState
|
||||
# Used for detecting VCRedist Installation
|
||||
!define INSTALLSTATE_DEFAULT "5"
|
||||
|
||||
!define INSTALLSTATE_DEFAULT "5"
|
||||
|
||||
Pop $R0
|
||||
StrCpy $NeedVcRedist "False"
|
||||
System::Call "msi::MsiQueryProductStateA(t '$R0') i.r0"
|
||||
StrCmp $0 ${INSTALLSTATE_DEFAULT} +2 0
|
||||
StrCpy $NeedVcRedist "True"
|
||||
Pop $R0
|
||||
StrCpy $NeedVcRedist "False"
|
||||
System::Call "msi::MsiQueryProductStateA(t '$R0') i.r0"
|
||||
StrCmp $0 ${INSTALLSTATE_DEFAULT} +2 0
|
||||
StrCpy $NeedVcRedist "True"
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Trim Function
|
||||
# - Trim whitespace from the beginning and end of a string
|
||||
# - Trims spaces, \r, \n, \t
|
||||
#
|
||||
# Usage:
|
||||
# Push " some string " ; String to Trim
|
||||
# Call Trim
|
||||
# Pop $0 ; Trimmed String: "some string"
|
||||
#
|
||||
# or
|
||||
#
|
||||
# ${Trim} $0 $1 ; Trimmed String, String to Trim
|
||||
#------------------------------------------------------------------------------
|
||||
Function Trim
|
||||
|
||||
Exch $R1 # Original string
|
||||
|
@ -580,6 +706,95 @@ Function Trim
|
|||
FunctionEnd
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# Explode Function
|
||||
# - Splits a string based off the passed separator
|
||||
# - Each item in the string is pushed to the stack
|
||||
# - The last item pushed to the stack is the length of the array
|
||||
#
|
||||
# Usage:
|
||||
# Push "," ; Separator
|
||||
# Push "string,to,separate" ; String to explode
|
||||
# Call Explode
|
||||
# Pop $0 ; Number of items in the array
|
||||
#
|
||||
# or
|
||||
#
|
||||
# ${Explode} $0 $1 $2 ; Length, Separator, String
|
||||
#------------------------------------------------------------------------------
|
||||
Function Explode
|
||||
# Initialize variables
|
||||
Var /GLOBAL explString
|
||||
Var /GLOBAL explSeparator
|
||||
Var /GLOBAL explStrLen
|
||||
Var /GLOBAL explSepLen
|
||||
Var /GLOBAL explOffset
|
||||
Var /GLOBAL explTmp
|
||||
Var /GLOBAL explTmp2
|
||||
Var /GLOBAL explTmp3
|
||||
Var /GLOBAL explArrCount
|
||||
|
||||
# Get input from user
|
||||
Pop $explString
|
||||
Pop $explSeparator
|
||||
|
||||
# Calculates initial values
|
||||
StrLen $explStrLen $explString
|
||||
StrLen $explSepLen $explSeparator
|
||||
StrCpy $explArrCount 1
|
||||
|
||||
${If} $explStrLen <= 1 # If we got a single character
|
||||
${OrIf} $explSepLen > $explStrLen # or separator is larger than the string,
|
||||
Push $explString # then we return initial string with no change
|
||||
Push 1 # and set array's length to 1
|
||||
Return
|
||||
${EndIf}
|
||||
|
||||
# Set offset to the last symbol of the string
|
||||
StrCpy $explOffset $explStrLen
|
||||
IntOp $explOffset $explOffset - 1
|
||||
|
||||
# Clear temp string to exclude the possibility of appearance of occasional data
|
||||
StrCpy $explTmp ""
|
||||
StrCpy $explTmp2 ""
|
||||
StrCpy $explTmp3 ""
|
||||
|
||||
# Loop until the offset becomes negative
|
||||
${Do}
|
||||
# If offset becomes negative, it is time to leave the function
|
||||
${IfThen} $explOffset == -1 ${|} ${ExitDo} ${|}
|
||||
|
||||
# Remove everything before and after the searched part ("TempStr")
|
||||
StrCpy $explTmp $explString $explSepLen $explOffset
|
||||
|
||||
${If} $explTmp == $explSeparator
|
||||
# Calculating offset to start copy from
|
||||
IntOp $explTmp2 $explOffset + $explSepLen # Offset equals to the current offset plus length of separator
|
||||
StrCpy $explTmp3 $explString "" $explTmp2
|
||||
|
||||
Push $explTmp3 # Throwing array item to the stack
|
||||
IntOp $explArrCount $explArrCount + 1 # Increasing array's counter
|
||||
|
||||
StrCpy $explString $explString $explOffset 0 # Cutting all characters beginning with the separator entry
|
||||
StrLen $explStrLen $explString
|
||||
${EndIf}
|
||||
|
||||
${If} $explOffset = 0 # If the beginning of the line met and there is no separator,
|
||||
# copying the rest of the string
|
||||
${If} $explSeparator == "" # Fix for the empty separator
|
||||
IntOp $explArrCount $explArrCount - 1
|
||||
${Else}
|
||||
Push $explString
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
IntOp $explOffset $explOffset - 1
|
||||
${Loop}
|
||||
|
||||
Push $explArrCount
|
||||
FunctionEnd
|
||||
|
||||
|
||||
#------------------------------------------------------------------------------
|
||||
# StrStr Function
|
||||
# - find substring in a string
|
||||
|
@ -816,6 +1031,9 @@ FunctionEnd
|
|||
###############################################################################
|
||||
Function getMinionConfig
|
||||
|
||||
# Set Config Found Default Value
|
||||
StrCpy $ExistingConfigFound 0
|
||||
|
||||
confFind:
|
||||
IfFileExists "$INSTDIR\conf\minion" confFound confNotFound
|
||||
|
||||
|
@ -828,24 +1046,42 @@ Function getMinionConfig
|
|||
${EndIf}
|
||||
|
||||
confFound:
|
||||
StrCpy $ExistingConfigFound 1
|
||||
FileOpen $0 "$INSTDIR\conf\minion" r
|
||||
|
||||
ClearErrors
|
||||
confLoop:
|
||||
FileRead $0 $1
|
||||
IfErrors EndOfFile
|
||||
${StrLoc} $2 $1 "master:" ">"
|
||||
${If} $2 == 0
|
||||
${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0"
|
||||
${Trim} $2 $2
|
||||
StrCpy $MasterHost_State $2
|
||||
ClearErrors # Clear Errors
|
||||
FileRead $0 $1 # Read the next line
|
||||
IfErrors EndOfFile # Error is probably EOF
|
||||
${StrLoc} $2 $1 "master:" ">" # Find `master:` starting at the beginning
|
||||
${If} $2 == 0 # If it found it in the first position, then it is defined
|
||||
${StrStrAdv} $2 $1 "master: " ">" ">" "0" "0" "0" # Read everything after `master: `
|
||||
${Trim} $2 $2 # Trim white space
|
||||
${If} $2 == "" # If it's empty, it's probably a list
|
||||
masterLoop:
|
||||
ClearErrors # Clear Errors
|
||||
FileRead $0 $1 # Read the next line
|
||||
IfErrors EndOfFile # Error is probably EOF
|
||||
${StrStrAdv} $2 $1 "- " ">" ">" "0" "0" "0" # Read everything after `- `
|
||||
${Trim} $2 $2 # Trim white space
|
||||
${IfNot} $2 == "" # If it's not empty, we found something
|
||||
${If} $ConfigMasterHost == "" # Is the default `salt` there
|
||||
StrCpy $ConfigMasterHost $2 # If so, make the first item the new entry
|
||||
${Else}
|
||||
StrCpy $ConfigMasterHost "$ConfigMasterHost,$2" # Append the new master, comma separated
|
||||
${EndIf}
|
||||
Goto masterLoop # Check the next one
|
||||
${EndIf}
|
||||
${Else}
|
||||
StrCpy $ConfigMasterHost $2 # A single master entry
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
|
||||
${StrLoc} $2 $1 "id:" ">"
|
||||
${If} $2 == 0
|
||||
${StrStrAdv} $2 $1 "id: " ">" ">" "0" "0" "0"
|
||||
${Trim} $2 $2
|
||||
StrCpy $MinionName_State $2
|
||||
StrCpy $ConfigMinionName $2
|
||||
${EndIf}
|
||||
|
||||
Goto confLoop
|
||||
|
@ -855,6 +1091,14 @@ Function getMinionConfig
|
|||
|
||||
confReallyNotFound:
|
||||
|
||||
# Set Default Config Values if not found
|
||||
${If} $ConfigMasterHost == ""
|
||||
StrCpy $ConfigMasterHost "salt"
|
||||
${EndIf}
|
||||
${If} $ConfigMinionName == ""
|
||||
StrCpy $ConfigMinionName "hostname"
|
||||
${EndIf}
|
||||
|
||||
FunctionEnd
|
||||
|
||||
|
||||
|
@ -874,7 +1118,22 @@ Function updateMinionConfig
|
|||
${StrLoc} $3 $2 "master:" ">" # where is 'master:' in this line
|
||||
${If} $3 == 0 # is it in the first...
|
||||
${OrIf} $3 == 1 # or second position (account for comments)
|
||||
StrCpy $2 "master: $MasterHost_State$\r$\n" # write the master
|
||||
|
||||
${Explode} $9 "," $MasterHost_state # Split the hostname on commas, $9 is the number of items found
|
||||
${If} $9 == 1 # 1 means only a single master was passed
|
||||
StrCpy $2 "master: $MasterHost_State$\r$\n" # write the master
|
||||
${Else} # Make a multi-master entry
|
||||
StrCpy $2 "master:" # Make the first line "master:"
|
||||
|
||||
loop_explode: # Start a loop to go through the list in the config
|
||||
pop $8 # Pop the next item off the stack
|
||||
${Trim} $8 $8 # Trim any whitespace
|
||||
StrCpy $2 "$2$\r$\n - $8" # Add it to the master variable ($2)
|
||||
IntOp $9 $9 - 1 # Decrement the list count
|
||||
${If} $9 >= 1 # If it's not 0
|
||||
Goto loop_explode # Do it again
|
||||
${EndIf} # close if statement
|
||||
${EndIf} # close if statement
|
||||
${EndIf} # close if statement
|
||||
${EndIf} # close if statement
|
||||
|
||||
|
@ -905,6 +1164,67 @@ Function parseCommandLineSwitches
|
|||
# Load the parameters
|
||||
${GetParameters} $R0
|
||||
|
||||
# Display Help
|
||||
ClearErrors
|
||||
${GetOptions} $R0 "/?" $R1
|
||||
IfErrors display_help_not_found
|
||||
|
||||
System::Call 'kernel32::GetStdHandle(i -11)i.r0'
|
||||
System::Call 'kernel32::AttachConsole(i -1)i.r1'
|
||||
${If} $0 = 0
|
||||
${OrIf} $1 = 0
|
||||
System::Call 'kernel32::AllocConsole()'
|
||||
System::Call 'kernel32::GetStdHandle(i -11)i.r0'
|
||||
${EndIf}
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "Help for Salt Minion installation$\n"
|
||||
FileWrite $0 "===============================================================================$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "/minion-name=$\t$\tA string value to set the minion name. Default is$\n"
|
||||
FileWrite $0 "$\t$\t$\t'hostname'. Setting the minion name will replace$\n"
|
||||
FileWrite $0 "$\t$\t$\texisting config with a default config. Cannot be$\n"
|
||||
FileWrite $0 "$\t$\t$\tused in conjunction with /use-existing-config=1$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "/master=$\t$\tA string value to set the IP address or hostname of$\n"
|
||||
FileWrite $0 "$\t$\t$\tthe master. Default value is 'salt'. You may pass a$\n"
|
||||
FileWrite $0 "$\t$\t$\tsingle master, or a comma separated list of masters.$\n"
|
||||
FileWrite $0 "$\t$\t$\tSetting the master will replace existing config with$\n"
|
||||
FileWrite $0 "$\t$\t$\ta default config. Cannot be used in conjunction with$\n"
|
||||
FileWrite $0 "$\t$\t$\t/use-existing-config=1$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "/start-minion=$\t$\t1 will start the service, 0 will not. Default is 1$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "/start-minion-delayed$\tSet the minion start type to 'Automatic (Delayed Start)'$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "/use-existing-config=$\t1 will use the existing config if present, 0 will$\n"
|
||||
FileWrite $0 "$\t$\t$\treplace existing config with a default config. Default$\n"
|
||||
FileWrite $0 "$\t$\t$\tis 1. If this is set to 1, values passed in$\n"
|
||||
FileWrite $0 "$\t$\t$\t/minion-name and /master will be ignored$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "/S$\t$\t$\tInstall Salt silently$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "/?$\t$\t$\tDisplay this help screen$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "-------------------------------------------------------------------------------$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "Examples:$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "${OutFile} /S$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "${OutFile} /S /minion-name=myminion /master=master.mydomain.com /start-minion-delayed$\n"
|
||||
FileWrite $0 "$\n"
|
||||
FileWrite $0 "===============================================================================$\n"
|
||||
FileWrite $0 "Press Enter to continue..."
|
||||
System::Free $0
|
||||
System::Free $1
|
||||
System::Call 'kernel32::FreeConsole()'
|
||||
Abort
|
||||
display_help_not_found:
|
||||
|
||||
# Set default value for Use Existing Config
|
||||
StrCpy $UseExistingConfig_State 1
|
||||
|
||||
# Check for start-minion switches
|
||||
# /start-service is to be deprecated, so we must check for both
|
||||
${GetOptions} $R0 "/start-service=" $R1
|
||||
|
@ -930,19 +1250,31 @@ Function parseCommandLineSwitches
|
|||
start_minion_delayed_not_found:
|
||||
|
||||
# Minion Config: Master IP/Name
|
||||
# If setting master, we don't want to use existing config
|
||||
${GetOptions} $R0 "/master=" $R1
|
||||
${IfNot} $R1 == ""
|
||||
StrCpy $MasterHost_State $R1
|
||||
StrCpy $UseExistingConfig_State 0
|
||||
${ElseIf} $MasterHost_State == ""
|
||||
StrCpy $MasterHost_State "salt"
|
||||
${EndIf}
|
||||
|
||||
# Minion Config: Minion ID
|
||||
# If setting minion id, we don't want to use existing config
|
||||
${GetOptions} $R0 "/minion-name=" $R1
|
||||
${IfNot} $R1 == ""
|
||||
StrCpy $MinionName_State $R1
|
||||
StrCpy $UseExistingConfig_State 0
|
||||
${ElseIf} $MinionName_State == ""
|
||||
StrCpy $MinionName_State "hostname"
|
||||
${EndIf}
|
||||
|
||||
# Use Existing Config
|
||||
# Overrides above settings with user passed settings
|
||||
${GetOptions} $R0 "/use-existing-config=" $R1
|
||||
${IfNot} $R1 == ""
|
||||
# Use Existing Config was passed something, set it
|
||||
StrCpy $UseExistingConfig_State $R1
|
||||
${EndIf}
|
||||
|
||||
FunctionEnd
|
||||
|
|
|
@ -9,3 +9,4 @@ SaltPyLint>=v2017.3.6
|
|||
pytest
|
||||
git+https://github.com/eisensheng/pytest-catchlog.git@develop#egg=Pytest-catchlog
|
||||
git+https://github.com/saltstack/pytest-salt.git@master#egg=pytest-salt
|
||||
testinfra>=1.7.0
|
||||
|
|
|
@ -13,3 +13,5 @@ httpretty
|
|||
SaltPyLint>=v2017.2.29
|
||||
pytest
|
||||
git+https://github.com/saltstack/pytest-salt.git@master#egg=pytest-salt
|
||||
git+https://github.com/eisensheng/pytest-catchlog.git@develop#egg=Pytest-catchlog
|
||||
testinfra>=1.7.0
|
||||
|
|
|
@ -12,7 +12,7 @@ found by reading the salt documentation:
|
|||
from __future__ import absolute_import
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.stringutils
|
||||
|
||||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
|
@ -31,13 +31,13 @@ class PublisherACL(object):
|
|||
Takes a username as a string and returns a boolean. True indicates that
|
||||
the provided user has been blacklisted
|
||||
'''
|
||||
return not salt.utils.check_whitelist_blacklist(user, blacklist=self.blacklist.get('users', []))
|
||||
return not salt.utils.stringutils.check_whitelist_blacklist(user, blacklist=self.blacklist.get('users', []))
|
||||
|
||||
def cmd_is_blacklisted(self, cmd):
|
||||
# If this is a regular command, it is a single function
|
||||
if isinstance(cmd, six.string_types):
|
||||
cmd = [cmd]
|
||||
for fun in cmd:
|
||||
if not salt.utils.check_whitelist_blacklist(fun, blacklist=self.blacklist.get('modules', [])):
|
||||
if not salt.utils.stringutils.check_whitelist_blacklist(fun, blacklist=self.blacklist.get('modules', [])):
|
||||
return True
|
||||
return False
|
||||
|
|
|
@ -6,8 +6,6 @@ This system allows for authentication to be managed in a module pluggable way
|
|||
so that any external authentication system can be used inside of Salt
|
||||
'''
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
# 1. Create auth loader instance
|
||||
# 2. Accept arguments as a dict
|
||||
# 3. Verify with function introspection
|
||||
|
@ -16,7 +14,7 @@ from __future__ import absolute_import
|
|||
# 6. Interface to verify tokens
|
||||
|
||||
# Import python libs
|
||||
from __future__ import print_function
|
||||
from __future__ import absolute_import, print_function
|
||||
import collections
|
||||
import time
|
||||
import logging
|
||||
|
@ -28,12 +26,13 @@ from salt.ext.six.moves import input
|
|||
import salt.config
|
||||
import salt.loader
|
||||
import salt.transport.client
|
||||
import salt.utils
|
||||
import salt.utils.args
|
||||
import salt.utils.dictupdate
|
||||
import salt.utils.files
|
||||
import salt.utils.minions
|
||||
import salt.utils.versions
|
||||
import salt.utils.user
|
||||
import salt.utils.versions
|
||||
import salt.utils.zeromq
|
||||
import salt.payload
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
@ -88,9 +87,10 @@ class LoadAuth(object):
|
|||
fstr = '{0}.auth'.format(load['eauth'])
|
||||
if fstr not in self.auth:
|
||||
return False
|
||||
fcall = salt.utils.format_call(self.auth[fstr],
|
||||
load,
|
||||
expected_extra_kws=AUTH_INTERNAL_KEYWORDS)
|
||||
fcall = salt.utils.args.format_call(
|
||||
self.auth[fstr],
|
||||
load,
|
||||
expected_extra_kws=AUTH_INTERNAL_KEYWORDS)
|
||||
try:
|
||||
if 'kwargs' in fcall:
|
||||
return self.auth[fstr](*fcall['args'], **fcall['kwargs'])
|
||||
|
@ -134,9 +134,10 @@ class LoadAuth(object):
|
|||
fstr = '{0}.acl'.format(mod)
|
||||
if fstr not in self.auth:
|
||||
return None
|
||||
fcall = salt.utils.format_call(self.auth[fstr],
|
||||
load,
|
||||
expected_extra_kws=AUTH_INTERNAL_KEYWORDS)
|
||||
fcall = salt.utils.args.format_call(
|
||||
self.auth[fstr],
|
||||
load,
|
||||
expected_extra_kws=AUTH_INTERNAL_KEYWORDS)
|
||||
try:
|
||||
return self.auth[fstr](*fcall['args'], **fcall['kwargs'])
|
||||
except Exception as e:
|
||||
|
@ -169,9 +170,10 @@ class LoadAuth(object):
|
|||
fstr = '{0}.groups'.format(load['eauth'])
|
||||
if fstr not in self.auth:
|
||||
return False
|
||||
fcall = salt.utils.format_call(self.auth[fstr],
|
||||
load,
|
||||
expected_extra_kws=AUTH_INTERNAL_KEYWORDS)
|
||||
fcall = salt.utils.args.format_call(
|
||||
self.auth[fstr],
|
||||
load,
|
||||
expected_extra_kws=AUTH_INTERNAL_KEYWORDS)
|
||||
try:
|
||||
return self.auth[fstr](*fcall['args'], **fcall['kwargs'])
|
||||
except IndexError:
|
||||
|
@ -426,13 +428,28 @@ class LoadAuth(object):
|
|||
|
||||
auth_list = self.get_auth_list(load)
|
||||
elif auth_type == 'user':
|
||||
if not self.authenticate_key(load, key):
|
||||
auth_ret = self.authenticate_key(load, key)
|
||||
msg = 'Authentication failure of type "user" occurred'
|
||||
if not auth_ret: # auth_ret can be a boolean or the effective user id
|
||||
if show_username:
|
||||
msg = 'Authentication failure of type "user" occurred for user {0}.'.format(username)
|
||||
else:
|
||||
msg = 'Authentication failure of type "user" occurred'
|
||||
msg = '{0} for user {1}.'.format(msg, username)
|
||||
ret['error'] = {'name': 'UserAuthenticationError', 'message': msg}
|
||||
return ret
|
||||
|
||||
# Verify that the caller has root on master
|
||||
if auth_ret is not True:
|
||||
if AuthUser(load['user']).is_sudo():
|
||||
if not self.opts['sudo_acl'] or not self.opts['publisher_acl']:
|
||||
auth_ret = True
|
||||
|
||||
if auth_ret is not True:
|
||||
# Avoid a circular import
|
||||
import salt.utils.master
|
||||
auth_list = salt.utils.master.get_values_of_matching_keys(
|
||||
self.opts['publisher_acl'], auth_ret)
|
||||
if not auth_list:
|
||||
ret['error'] = {'name': 'UserAuthenticationError', 'message': msg}
|
||||
return ret
|
||||
else:
|
||||
ret['error'] = {'name': 'SaltInvocationError',
|
||||
'message': 'Authentication type not supported.'}
|
||||
|
@ -653,7 +670,7 @@ class Resolver(object):
|
|||
|
||||
def _send_token_request(self, load):
|
||||
if self.opts['transport'] in ('zeromq', 'tcp'):
|
||||
master_uri = 'tcp://' + salt.utils.ip_bracket(self.opts['interface']) + \
|
||||
master_uri = 'tcp://' + salt.utils.zeromq.ip_bracket(self.opts['interface']) + \
|
||||
':' + str(self.opts['ret_port'])
|
||||
channel = salt.transport.client.ReqChannel.factory(self.opts,
|
||||
crypt='clear',
|
||||
|
|
|
@ -110,6 +110,10 @@ class _LDAPConnection(object):
|
|||
self.ldap.set_option(ldap.OPT_REFERRALS, 0) # Needed for AD
|
||||
|
||||
if not anonymous:
|
||||
if self.bindpw is None or len(self.bindpw) < 1:
|
||||
raise CommandExecutionError(
|
||||
'LDAP bind password is not set: password cannot be empty if auth.ldap.anonymous is False'
|
||||
)
|
||||
self.ldap.simple_bind_s(self.binddn, self.bindpw)
|
||||
except Exception as ldap_error:
|
||||
raise CommandExecutionError(
|
||||
|
|
|
@ -10,7 +10,7 @@ import re
|
|||
|
||||
# Import Salt libs
|
||||
import salt.loader
|
||||
import salt.utils
|
||||
import salt.utils.event
|
||||
import salt.utils.minion
|
||||
from salt.ext.six.moves import map
|
||||
from salt.exceptions import CommandExecutionError
|
||||
|
@ -199,13 +199,42 @@ class Beacon(object):
|
|||
else:
|
||||
self.opts['beacons'][name].append({'enabled': enabled_value})
|
||||
|
||||
def list_beacons(self):
|
||||
def _get_beacons(self,
|
||||
include_opts=True,
|
||||
include_pillar=True):
|
||||
'''
|
||||
Return the beacons data structure
|
||||
'''
|
||||
beacons = {}
|
||||
if include_pillar:
|
||||
pillar_beacons = self.opts.get('pillar', {}).get('beacons', {})
|
||||
if not isinstance(pillar_beacons, dict):
|
||||
raise ValueError('Beacons must be of type dict.')
|
||||
beacons.update(pillar_beacons)
|
||||
if include_opts:
|
||||
opts_beacons = self.opts.get('beacons', {})
|
||||
if not isinstance(opts_beacons, dict):
|
||||
raise ValueError('Beacons must be of type dict.')
|
||||
beacons.update(opts_beacons)
|
||||
return beacons
|
||||
|
||||
def list_beacons(self,
|
||||
include_pillar=True,
|
||||
include_opts=True):
|
||||
'''
|
||||
List the beacon items
|
||||
|
||||
include_pillar: Whether to include beacons that are
|
||||
configured in pillar, default is True.
|
||||
|
||||
include_opts: Whether to include beacons that are
|
||||
configured in opts, default is True.
|
||||
'''
|
||||
beacons = self._get_beacons(include_pillar, include_opts)
|
||||
|
||||
# Fire the complete event back along with the list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
|
||||
evt.fire_event({'complete': True, 'beacons': beacons},
|
||||
tag='/salt/minion/minion_beacons_list_complete')
|
||||
|
||||
return True
|
||||
|
@ -236,8 +265,8 @@ class Beacon(object):
|
|||
del beacon_data['enabled']
|
||||
valid, vcomment = self.beacons[validate_str](beacon_data)
|
||||
else:
|
||||
log.info('Beacon %s does not have a validate'
|
||||
' function, skipping validation.', name)
|
||||
vcomment = 'Beacon {0} does not have a validate' \
|
||||
' function, skipping validation.'.format(name)
|
||||
valid = True
|
||||
|
||||
# Fire the complete event back along with the list of beacons
|
||||
|
@ -257,16 +286,23 @@ class Beacon(object):
|
|||
data = {}
|
||||
data[name] = beacon_data
|
||||
|
||||
if name in self.opts['beacons']:
|
||||
log.info('Updating settings for beacon '
|
||||
'item: %s', name)
|
||||
if name in self._get_beacons(include_opts=False):
|
||||
comment = 'Cannot update beacon item {0}, ' \
|
||||
'because it is configured in pillar.'.format(name)
|
||||
complete = False
|
||||
else:
|
||||
log.info('Added new beacon item %s', name)
|
||||
self.opts['beacons'].update(data)
|
||||
if name in self.opts['beacons']:
|
||||
comment = 'Updating settings for beacon ' \
|
||||
'item: {0}'.format(name)
|
||||
else:
|
||||
comment = 'Added new beacon item: {0}'.format(name)
|
||||
complete = True
|
||||
self.opts['beacons'].update(data)
|
||||
|
||||
# Fire the complete event back along with updated list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
|
||||
evt.fire_event({'complete': complete, 'comment': comment,
|
||||
'beacons': self.opts['beacons']},
|
||||
tag='/salt/minion/minion_beacon_add_complete')
|
||||
|
||||
return True
|
||||
|
@ -279,13 +315,20 @@ class Beacon(object):
|
|||
data = {}
|
||||
data[name] = beacon_data
|
||||
|
||||
log.info('Updating settings for beacon '
|
||||
'item: %s', name)
|
||||
self.opts['beacons'].update(data)
|
||||
if name in self._get_beacons(include_opts=False):
|
||||
comment = 'Cannot modify beacon item {0}, ' \
|
||||
'it is configured in pillar.'.format(name)
|
||||
complete = False
|
||||
else:
|
||||
comment = 'Updating settings for beacon ' \
|
||||
'item: {0}'.format(name)
|
||||
complete = True
|
||||
self.opts['beacons'].update(data)
|
||||
|
||||
# Fire the complete event back along with updated list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
|
||||
evt.fire_event({'complete': complete, 'comment': comment,
|
||||
'beacons': self.opts['beacons']},
|
||||
tag='/salt/minion/minion_beacon_modify_complete')
|
||||
|
||||
return True
|
||||
|
@ -295,13 +338,22 @@ class Beacon(object):
|
|||
Delete a beacon item
|
||||
'''
|
||||
|
||||
if name in self.opts['beacons']:
|
||||
log.info('Deleting beacon item %s', name)
|
||||
del self.opts['beacons'][name]
|
||||
if name in self._get_beacons(include_opts=False):
|
||||
comment = 'Cannot delete beacon item {0}, ' \
|
||||
'it is configured in pillar.'.format(name)
|
||||
complete = False
|
||||
else:
|
||||
if name in self.opts['beacons']:
|
||||
del self.opts['beacons'][name]
|
||||
comment = 'Deleting beacon item: {0}'.format(name)
|
||||
else:
|
||||
comment = 'Beacon item {0} not found.'.format(name)
|
||||
complete = True
|
||||
|
||||
# Fire the complete event back along with updated list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
|
||||
evt.fire_event({'complete': complete, 'comment': comment,
|
||||
'beacons': self.opts['beacons']},
|
||||
tag='/salt/minion/minion_beacon_delete_complete')
|
||||
|
||||
return True
|
||||
|
@ -339,11 +391,19 @@ class Beacon(object):
|
|||
Enable a beacon
|
||||
'''
|
||||
|
||||
self._update_enabled(name, True)
|
||||
if name in self._get_beacons(include_opts=False):
|
||||
comment = 'Cannot enable beacon item {0}, ' \
|
||||
'it is configured in pillar.'.format(name)
|
||||
complete = False
|
||||
else:
|
||||
self._update_enabled(name, True)
|
||||
comment = 'Enabling beacon item {0}'.format(name)
|
||||
complete = True
|
||||
|
||||
# Fire the complete event back along with updated list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
|
||||
evt.fire_event({'complete': complete, 'comment': comment,
|
||||
'beacons': self.opts['beacons']},
|
||||
tag='/salt/minion/minion_beacon_enabled_complete')
|
||||
|
||||
return True
|
||||
|
@ -353,11 +413,19 @@ class Beacon(object):
|
|||
Disable a beacon
|
||||
'''
|
||||
|
||||
self._update_enabled(name, False)
|
||||
if name in self._get_beacons(include_opts=False):
|
||||
comment = 'Cannot disable beacon item {0}, ' \
|
||||
'it is configured in pillar.'.format(name)
|
||||
complete = False
|
||||
else:
|
||||
self._update_enabled(name, False)
|
||||
comment = 'Disabling beacon item {0}'.format(name)
|
||||
complete = True
|
||||
|
||||
# Fire the complete event back along with updated list of beacons
|
||||
evt = salt.utils.event.get_event('minion', opts=self.opts)
|
||||
evt.fire_event({'complete': True, 'beacons': self.opts['beacons']},
|
||||
evt.fire_event({'complete': complete, 'comment': comment,
|
||||
'beacons': self.opts['beacons']},
|
||||
tag='/salt/minion/minion_beacon_disabled_complete')
|
||||
|
||||
return True
|
||||
|
|
|
@ -7,7 +7,7 @@ A simple beacon to watch journald for specific entries
|
|||
from __future__ import absolute_import
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.data
|
||||
import salt.utils.locales
|
||||
import salt.ext.six
|
||||
from salt.ext.six.moves import map
|
||||
|
@ -99,7 +99,7 @@ def beacon(config):
|
|||
n_flag += 1
|
||||
if n_flag == len(_config['services'][name]):
|
||||
# Match!
|
||||
sub = salt.utils.simple_types_filter(cur)
|
||||
sub = salt.utils.data.simple_types_filter(cur)
|
||||
sub.update({'tag': name})
|
||||
ret.append(sub)
|
||||
return ret
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
Send events covering service status
|
||||
Send events covering process status
|
||||
'''
|
||||
|
||||
# Import Python Libs
|
||||
|
|
|
@ -3,6 +3,8 @@
|
|||
Beacon to monitor temperature, humidity and pressure using the SenseHat
|
||||
of a Raspberry Pi.
|
||||
|
||||
.. versionadded:: 2017.7.0
|
||||
|
||||
:maintainer: Benedikt Werner <1benediktwerner@gmail.com>
|
||||
:maturity: new
|
||||
:depends: sense_hat Python module
|
||||
|
|
|
@ -8,7 +8,6 @@ from __future__ import absolute_import
|
|||
import time
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.path
|
||||
import salt.utils.vt
|
||||
|
||||
|
|
1
salt/cache/localfs.py
vendored
1
salt/cache/localfs.py
vendored
|
@ -18,7 +18,6 @@ import shutil
|
|||
import tempfile
|
||||
|
||||
from salt.exceptions import SaltCacheError
|
||||
import salt.utils
|
||||
import salt.utils.atomicfile
|
||||
import salt.utils.files
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ import copy
|
|||
from datetime import datetime, timedelta
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils # Can be removed once print_cli is moved
|
||||
import salt.utils.stringutils
|
||||
import salt.client
|
||||
import salt.output
|
||||
import salt.exceptions
|
||||
|
@ -73,7 +73,7 @@ class Batch(object):
|
|||
m = next(six.iterkeys(ret))
|
||||
except StopIteration:
|
||||
if not self.quiet:
|
||||
salt.utils.print_cli('No minions matched the target.')
|
||||
salt.utils.stringutils.print_cli('No minions matched the target.')
|
||||
break
|
||||
if m is not None:
|
||||
fret.add(m)
|
||||
|
@ -95,7 +95,7 @@ class Batch(object):
|
|||
return int(self.opts['batch'])
|
||||
except ValueError:
|
||||
if not self.quiet:
|
||||
salt.utils.print_cli('Invalid batch data sent: {0}\nData must be in the '
|
||||
salt.utils.stringutils.print_cli('Invalid batch data sent: {0}\nData must be in the '
|
||||
'form of %10, 10% or 3'.format(self.opts['batch']))
|
||||
|
||||
def __update_wait(self, wait):
|
||||
|
@ -147,7 +147,7 @@ class Batch(object):
|
|||
# We already know some minions didn't respond to the ping, so inform
|
||||
# the user we won't be attempting to run a job on them
|
||||
for down_minion in self.down_minions:
|
||||
salt.utils.print_cli('Minion {0} did not respond. No job will be sent.'.format(down_minion))
|
||||
salt.utils.stringutils.print_cli('Minion {0} did not respond. No job will be sent.'.format(down_minion))
|
||||
|
||||
# Iterate while we still have things to execute
|
||||
while len(ret) < len(self.minions):
|
||||
|
@ -172,7 +172,7 @@ class Batch(object):
|
|||
|
||||
if next_:
|
||||
if not self.quiet:
|
||||
salt.utils.print_cli('\nExecuting run on {0}\n'.format(sorted(next_)))
|
||||
salt.utils.stringutils.print_cli('\nExecuting run on {0}\n'.format(sorted(next_)))
|
||||
# create a new iterator for this batch of minions
|
||||
new_iter = self.local.cmd_iter_no_block(
|
||||
*args,
|
||||
|
@ -219,14 +219,14 @@ class Batch(object):
|
|||
if part['data']['id'] in minion_tracker[queue]['minions']:
|
||||
minion_tracker[queue]['minions'].remove(part['data']['id'])
|
||||
else:
|
||||
salt.utils.print_cli('minion {0} was already deleted from tracker, probably a duplicate key'.format(part['id']))
|
||||
salt.utils.stringutils.print_cli('minion {0} was already deleted from tracker, probably a duplicate key'.format(part['id']))
|
||||
else:
|
||||
parts.update(part)
|
||||
for id in part:
|
||||
if id in minion_tracker[queue]['minions']:
|
||||
minion_tracker[queue]['minions'].remove(id)
|
||||
else:
|
||||
salt.utils.print_cli('minion {0} was already deleted from tracker, probably a duplicate key'.format(id))
|
||||
salt.utils.stringutils.print_cli('minion {0} was already deleted from tracker, probably a duplicate key'.format(id))
|
||||
except StopIteration:
|
||||
# if a iterator is done:
|
||||
# - set it to inactive
|
||||
|
|
|
@ -20,12 +20,13 @@ import salt.minion
|
|||
import salt.output
|
||||
import salt.payload
|
||||
import salt.transport
|
||||
import salt.utils # Can be removed once print_cli, activate_profile, and output_profile are moved
|
||||
import salt.utils.args
|
||||
import salt.utils.files
|
||||
import salt.utils.jid
|
||||
import salt.utils.kinds as kinds
|
||||
import salt.utils.minion
|
||||
import salt.utils.profile
|
||||
import salt.utils.stringutils
|
||||
import salt.defaults.exitcodes
|
||||
from salt.cli import daemons
|
||||
from salt.log import LOG_LEVELS
|
||||
|
@ -113,7 +114,7 @@ class BaseCaller(object):
|
|||
docs[name] = func.__doc__
|
||||
for name in sorted(docs):
|
||||
if name.startswith(self.opts.get('fun', '')):
|
||||
salt.utils.print_cli('{0}:\n{1}\n'.format(name, docs[name]))
|
||||
salt.utils.stringutils.print_cli('{0}:\n{1}\n'.format(name, docs[name]))
|
||||
|
||||
def print_grains(self):
|
||||
'''
|
||||
|
@ -128,11 +129,11 @@ class BaseCaller(object):
|
|||
'''
|
||||
profiling_enabled = self.opts.get('profiling_enabled', False)
|
||||
try:
|
||||
pr = salt.utils.activate_profile(profiling_enabled)
|
||||
pr = salt.utils.profile.activate_profile(profiling_enabled)
|
||||
try:
|
||||
ret = self.call()
|
||||
finally:
|
||||
salt.utils.output_profile(
|
||||
salt.utils.profile.output_profile(
|
||||
pr,
|
||||
stats_path=self.opts.get('profiling_path', '/tmp/stats'),
|
||||
stop=True)
|
||||
|
@ -209,7 +210,7 @@ class BaseCaller(object):
|
|||
ret['return'] = func(*args, **kwargs)
|
||||
except TypeError as exc:
|
||||
sys.stderr.write('\nPassed invalid arguments: {0}.\n\nUsage:\n'.format(exc))
|
||||
salt.utils.print_cli(func.__doc__)
|
||||
salt.utils.stringutils.print_cli(func.__doc__)
|
||||
active_level = LOG_LEVELS.get(
|
||||
self.opts['log_level'].lower(), logging.ERROR)
|
||||
if active_level <= logging.DEBUG:
|
||||
|
|
|
@ -19,7 +19,6 @@ import sys
|
|||
# Import salt libs
|
||||
import salt.client
|
||||
import salt.output
|
||||
import salt.utils
|
||||
import salt.utils.files
|
||||
import salt.utils.gzip_util
|
||||
import salt.utils.itertools
|
||||
|
@ -127,9 +126,10 @@ class SaltCP(object):
|
|||
if os.path.isfile(fn_):
|
||||
files.update(self._file_dict(fn_))
|
||||
elif os.path.isdir(fn_):
|
||||
salt.utils.print_cli(fn_ + ' is a directory, only files are supported '
|
||||
'in non-chunked mode. Use "--chunked" command '
|
||||
'line argument.')
|
||||
salt.utils.stringutils.print_cli(
|
||||
fn_ + ' is a directory, only files are supported '
|
||||
'in non-chunked mode. Use "--chunked" command '
|
||||
'line argument.')
|
||||
sys.exit(1)
|
||||
return files
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ from salt.utils import migrations
|
|||
import salt.utils.kinds as kinds
|
||||
|
||||
try:
|
||||
from salt.utils import ip_bracket
|
||||
from salt.utils.zeromq import ip_bracket
|
||||
import salt.utils.parsers
|
||||
from salt.utils.verify import check_user, verify_env, verify_socket
|
||||
except ImportError as exc:
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
from __future__ import print_function
|
||||
from __future__ import absolute_import
|
||||
|
||||
import salt.utils # Can be removed once activate_profile and output_profile are moved
|
||||
import salt.utils.parsers
|
||||
import salt.utils.profile
|
||||
from salt.utils.verify import check_user, verify_log
|
||||
from salt.exceptions import SaltClientError
|
||||
import salt.defaults.exitcodes # pylint: disable=W0611
|
||||
|
@ -35,7 +35,7 @@ class SaltRun(salt.utils.parsers.SaltRunOptionParser):
|
|||
# someone tries to use the runners via the python API
|
||||
try:
|
||||
if check_user(self.config['user']):
|
||||
pr = salt.utils.activate_profile(profiling_enabled)
|
||||
pr = salt.utils.profile.activate_profile(profiling_enabled)
|
||||
try:
|
||||
ret = runner.run()
|
||||
# In older versions ret['data']['retcode'] was used
|
||||
|
@ -49,7 +49,7 @@ class SaltRun(salt.utils.parsers.SaltRunOptionParser):
|
|||
elif isinstance(ret, dict) and 'retcode' in ret.get('data', {}):
|
||||
self.exit(ret['data']['retcode'])
|
||||
finally:
|
||||
salt.utils.output_profile(
|
||||
salt.utils.profile.output_profile(
|
||||
pr,
|
||||
stats_path=self.options.profiling_path,
|
||||
stop=True)
|
||||
|
|
|
@ -7,15 +7,18 @@ sys.modules['pkg_resources'] = None
|
|||
import os
|
||||
|
||||
# Import Salt libs
|
||||
import salt.utils # Can be removed once print_cli is moved
|
||||
import salt.utils.job
|
||||
import salt.utils.parsers
|
||||
import salt.utils.stringutils
|
||||
from salt.utils.args import yamlify_arg
|
||||
from salt.utils.verify import verify_log
|
||||
from salt.exceptions import (
|
||||
SaltClientError,
|
||||
SaltInvocationError,
|
||||
EauthAuthenticationError
|
||||
)
|
||||
EauthAuthenticationError,
|
||||
LoaderError,
|
||||
SaltClientError,
|
||||
SaltInvocationError,
|
||||
SaltSystemExit
|
||||
)
|
||||
|
||||
# Import 3rd-party libs
|
||||
from salt.ext import six
|
||||
|
@ -93,7 +96,7 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
# potentially switch to batch execution
|
||||
if self.options.batch_safe_limit > 1:
|
||||
if len(self._preview_target()) >= self.options.batch_safe_limit:
|
||||
salt.utils.print_cli('\nNOTICE: Too many minions targeted, switching to batch execution.')
|
||||
salt.utils.stringutils.print_cli('\nNOTICE: Too many minions targeted, switching to batch execution.')
|
||||
self.options.batch = self.options.batch_safe_size
|
||||
self._run_batch()
|
||||
return
|
||||
|
@ -140,7 +143,7 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
|
||||
if self.config['async']:
|
||||
jid = self.local_client.cmd_async(**kwargs)
|
||||
salt.utils.print_cli('Executed command with job ID: {0}'.format(jid))
|
||||
salt.utils.stringutils.print_cli('Executed command with job ID: {0}'.format(jid))
|
||||
return
|
||||
|
||||
# local will be None when there was an error
|
||||
|
@ -166,8 +169,8 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
out = 'progress'
|
||||
try:
|
||||
self._progress_ret(progress, out)
|
||||
except salt.exceptions.LoaderError as exc:
|
||||
raise salt.exceptions.SaltSystemExit(exc)
|
||||
except LoaderError as exc:
|
||||
raise SaltSystemExit(exc)
|
||||
if 'return_count' not in progress:
|
||||
ret.update(progress)
|
||||
self._progress_end(out)
|
||||
|
@ -250,7 +253,7 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
|
||||
try:
|
||||
batch = salt.cli.batch.Batch(self.config, eauth=eauth, quiet=True)
|
||||
except salt.exceptions.SaltClientError as exc:
|
||||
except SaltClientError:
|
||||
sys.exit(2)
|
||||
|
||||
ret = {}
|
||||
|
@ -264,7 +267,7 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
try:
|
||||
self.config['batch'] = self.options.batch
|
||||
batch = salt.cli.batch.Batch(self.config, eauth=eauth, parser=self.options)
|
||||
except salt.exceptions.SaltClientError as exc:
|
||||
except SaltClientError:
|
||||
# We will print errors to the console further down the stack
|
||||
sys.exit(1)
|
||||
# Printing the output is already taken care of in run() itself
|
||||
|
@ -279,12 +282,12 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
|
||||
def _print_errors_summary(self, errors):
|
||||
if errors:
|
||||
salt.utils.print_cli('\n')
|
||||
salt.utils.print_cli('---------------------------')
|
||||
salt.utils.print_cli('Errors')
|
||||
salt.utils.print_cli('---------------------------')
|
||||
salt.utils.stringutils.print_cli('\n')
|
||||
salt.utils.stringutils.print_cli('---------------------------')
|
||||
salt.utils.stringutils.print_cli('Errors')
|
||||
salt.utils.stringutils.print_cli('---------------------------')
|
||||
for error in errors:
|
||||
salt.utils.print_cli(self._format_error(error))
|
||||
salt.utils.stringutils.print_cli(self._format_error(error))
|
||||
|
||||
def _print_returns_summary(self, ret):
|
||||
'''
|
||||
|
@ -314,22 +317,22 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
return_counter += 1
|
||||
if self._get_retcode(ret[each_minion]):
|
||||
failed_minions.append(each_minion)
|
||||
salt.utils.print_cli('\n')
|
||||
salt.utils.print_cli('-------------------------------------------')
|
||||
salt.utils.print_cli('Summary')
|
||||
salt.utils.print_cli('-------------------------------------------')
|
||||
salt.utils.print_cli('# of minions targeted: {0}'.format(return_counter + not_return_counter))
|
||||
salt.utils.print_cli('# of minions returned: {0}'.format(return_counter))
|
||||
salt.utils.print_cli('# of minions that did not return: {0}'.format(not_return_counter))
|
||||
salt.utils.print_cli('# of minions with errors: {0}'.format(len(failed_minions)))
|
||||
salt.utils.stringutils.print_cli('\n')
|
||||
salt.utils.stringutils.print_cli('-------------------------------------------')
|
||||
salt.utils.stringutils.print_cli('Summary')
|
||||
salt.utils.stringutils.print_cli('-------------------------------------------')
|
||||
salt.utils.stringutils.print_cli('# of minions targeted: {0}'.format(return_counter + not_return_counter))
|
||||
salt.utils.stringutils.print_cli('# of minions returned: {0}'.format(return_counter))
|
||||
salt.utils.stringutils.print_cli('# of minions that did not return: {0}'.format(not_return_counter))
|
||||
salt.utils.stringutils.print_cli('# of minions with errors: {0}'.format(len(failed_minions)))
|
||||
if self.options.verbose:
|
||||
if not_connected_minions:
|
||||
salt.utils.print_cli('Minions not connected: {0}'.format(" ".join(not_connected_minions)))
|
||||
salt.utils.stringutils.print_cli('Minions not connected: {0}'.format(" ".join(not_connected_minions)))
|
||||
if not_response_minions:
|
||||
salt.utils.print_cli('Minions not responding: {0}'.format(" ".join(not_response_minions)))
|
||||
salt.utils.stringutils.print_cli('Minions not responding: {0}'.format(" ".join(not_response_minions)))
|
||||
if failed_minions:
|
||||
salt.utils.print_cli('Minions with failures: {0}'.format(" ".join(failed_minions)))
|
||||
salt.utils.print_cli('-------------------------------------------')
|
||||
salt.utils.stringutils.print_cli('Minions with failures: {0}'.format(" ".join(failed_minions)))
|
||||
salt.utils.stringutils.print_cli('-------------------------------------------')
|
||||
|
||||
def _progress_end(self, out):
|
||||
import salt.output
|
||||
|
@ -344,9 +347,9 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
if not hasattr(self, 'progress_bar'):
|
||||
try:
|
||||
self.progress_bar = salt.output.get_progress(self.config, out, progress)
|
||||
except Exception as exc:
|
||||
raise salt.exceptions.LoaderError('\nWARNING: Install the `progressbar` python package. '
|
||||
'Requested job was still run but output cannot be displayed.\n')
|
||||
except Exception:
|
||||
raise LoaderError('\nWARNING: Install the `progressbar` python package. '
|
||||
'Requested job was still run but output cannot be displayed.\n')
|
||||
salt.output.update_progress(self.config, progress, self.progress_bar, out)
|
||||
|
||||
def _output_ret(self, ret, out):
|
||||
|
@ -421,6 +424,6 @@ class SaltCMD(salt.utils.parsers.SaltCMDOptionParser):
|
|||
salt.output.display_output({fun: docs[fun]}, 'nested', self.config)
|
||||
else:
|
||||
for fun in sorted(docs):
|
||||
salt.utils.print_cli('{0}:'.format(fun))
|
||||
salt.utils.print_cli(docs[fun])
|
||||
salt.utils.print_cli('')
|
||||
salt.utils.stringutils.print_cli('{0}:'.format(fun))
|
||||
salt.utils.stringutils.print_cli(docs[fun])
|
||||
salt.utils.stringutils.print_cli('')
|
||||
|
|
|
@ -32,16 +32,16 @@ import salt.cache
|
|||
import salt.payload
|
||||
import salt.transport
|
||||
import salt.loader
|
||||
import salt.utils # Can be removed once ip_bracket is moved
|
||||
import salt.utils.args
|
||||
import salt.utils.event
|
||||
import salt.utils.files
|
||||
import salt.utils.jid
|
||||
import salt.utils.minions
|
||||
import salt.utils.platform
|
||||
import salt.utils.user
|
||||
import salt.utils.verify
|
||||
import salt.utils.versions
|
||||
import salt.utils.jid
|
||||
import salt.utils.zeromq
|
||||
import salt.syspaths as syspaths
|
||||
from salt.exceptions import (
|
||||
EauthAuthenticationError, SaltInvocationError, SaltReqTimeoutError,
|
||||
|
@ -1595,7 +1595,10 @@ class LocalClient(object):
|
|||
timeout=timeout,
|
||||
tgt=tgt,
|
||||
tgt_type=tgt_type,
|
||||
expect_minions=(verbose or show_timeout),
|
||||
# (gtmanfred) expect_minions is popped here incase it is passed from a client
|
||||
# call. If this is not popped, then it would be passed twice to
|
||||
# get_iter_returns.
|
||||
expect_minions=(kwargs.pop('expect_minions', False) or verbose or show_timeout),
|
||||
**kwargs
|
||||
):
|
||||
log.debug(u'return event: %s', ret)
|
||||
|
@ -1791,7 +1794,7 @@ class LocalClient(object):
|
|||
timeout,
|
||||
**kwargs)
|
||||
|
||||
master_uri = u'tcp://' + salt.utils.ip_bracket(self.opts[u'interface']) + \
|
||||
master_uri = u'tcp://' + salt.utils.zeromq.ip_bracket(self.opts[u'interface']) + \
|
||||
u':' + str(self.opts[u'ret_port'])
|
||||
channel = salt.transport.Channel.factory(self.opts,
|
||||
crypt=u'clear',
|
||||
|
@ -1899,7 +1902,7 @@ class LocalClient(object):
|
|||
timeout,
|
||||
**kwargs)
|
||||
|
||||
master_uri = u'tcp://' + salt.utils.ip_bracket(self.opts[u'interface']) + \
|
||||
master_uri = u'tcp://' + salt.utils.zeromq.ip_bracket(self.opts[u'interface']) + \
|
||||
u':' + str(self.opts[u'ret_port'])
|
||||
channel = salt.transport.client.AsyncReqChannel.factory(self.opts,
|
||||
io_loop=io_loop,
|
||||
|
|
|
@ -16,7 +16,6 @@ import copy as pycopy
|
|||
# Import Salt libs
|
||||
import salt.exceptions
|
||||
import salt.minion
|
||||
import salt.utils # Can be removed once daemonize, format_call are moved
|
||||
import salt.utils.args
|
||||
import salt.utils.doc
|
||||
import salt.utils.error
|
||||
|
@ -371,7 +370,7 @@ class SyncClientMixin(object):
|
|||
args = low[u'arg']
|
||||
kwargs = low[u'kwarg']
|
||||
else:
|
||||
f_call = salt.utils.format_call(
|
||||
f_call = salt.utils.args.format_call(
|
||||
self.functions[fun],
|
||||
low,
|
||||
expected_extra_kws=CLIENT_INTERNAL_KEYWORDS
|
||||
|
@ -469,7 +468,7 @@ class AsyncClientMixin(object):
|
|||
# Shutdown the multiprocessing before daemonizing
|
||||
salt.log.setup.shutdown_multiprocessing_logging()
|
||||
|
||||
salt.utils.daemonize()
|
||||
salt.utils.process.daemonize()
|
||||
|
||||
# Reconfigure multiprocessing logging after daemonizing
|
||||
salt.log.setup.setup_multiprocessing_logging()
|
||||
|
|
|
@ -36,11 +36,12 @@ import salt.minion
|
|||
import salt.roster
|
||||
import salt.serializers.yaml
|
||||
import salt.state
|
||||
import salt.utils
|
||||
import salt.utils.args
|
||||
import salt.utils.atomicfile
|
||||
import salt.utils.event
|
||||
import salt.utils.files
|
||||
import salt.utils.hashutils
|
||||
import salt.utils.json
|
||||
import salt.utils.network
|
||||
import salt.utils.path
|
||||
import salt.utils.stringutils
|
||||
|
@ -496,7 +497,7 @@ class SSH(object):
|
|||
**target)
|
||||
stdout, stderr, retcode = single.cmd_block()
|
||||
try:
|
||||
data = salt.utils.find_json(stdout)
|
||||
data = salt.utils.json.find_json(stdout)
|
||||
return {host: data.get(u'local', data)}
|
||||
except Exception:
|
||||
if stderr:
|
||||
|
@ -524,7 +525,7 @@ class SSH(object):
|
|||
stdout, stderr, retcode = single.run()
|
||||
# This job is done, yield
|
||||
try:
|
||||
data = salt.utils.find_json(stdout)
|
||||
data = salt.utils.json.find_json(stdout)
|
||||
if len(data) < 2 and u'local' in data:
|
||||
ret[u'ret'] = data[u'local']
|
||||
else:
|
||||
|
@ -1507,7 +1508,7 @@ def mod_data(fsclient):
|
|||
if not os.path.isfile(mod_path):
|
||||
continue
|
||||
mods_data[os.path.basename(fn_)] = mod_path
|
||||
chunk = salt.utils.get_hash(mod_path)
|
||||
chunk = salt.utils.hashutils.get_hash(mod_path)
|
||||
ver_base += chunk
|
||||
if mods_data:
|
||||
if ref in ret:
|
||||
|
|
|
@ -15,7 +15,6 @@ import subprocess
|
|||
|
||||
# Import salt libs
|
||||
import salt.defaults.exitcodes
|
||||
import salt.utils
|
||||
import salt.utils.nb_popen
|
||||
import salt.utils.vt
|
||||
|
||||
|
|
|
@ -137,7 +137,7 @@ def need_deployment():
|
|||
sys.exit(EX_THIN_DEPLOY)
|
||||
|
||||
|
||||
# Adapted from salt.utils.get_hash()
|
||||
# Adapted from salt.utils.hashutils.get_hash()
|
||||
def get_hash(path, form=u'sha1', chunk_size=4096):
|
||||
'''
|
||||
Generate a hash digest string for a file.
|
||||
|
|
|
@ -13,7 +13,7 @@ import copy
|
|||
|
||||
# Import salt libs
|
||||
import salt.loader
|
||||
import salt.utils
|
||||
import salt.utils.data
|
||||
import salt.client.ssh
|
||||
|
||||
# Import 3rd-party libs
|
||||
|
@ -121,7 +121,7 @@ class FunctionWrapper(object):
|
|||
u'stderr': stderr,
|
||||
u'retcode': retcode}
|
||||
try:
|
||||
ret = json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
ret = json.loads(stdout, object_hook=salt.utils.data.decode_dict)
|
||||
if len(ret) < 2 and u'local' in ret:
|
||||
ret = ret[u'local']
|
||||
ret = ret.get(u'return', {})
|
||||
|
|
|
@ -9,7 +9,8 @@ import re
|
|||
import os
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.data
|
||||
import salt.utils.files
|
||||
import salt.syspaths as syspaths
|
||||
|
||||
# Import 3rd-party libs
|
||||
|
@ -81,7 +82,7 @@ def manage_mode(mode):
|
|||
# config.manage_mode should no longer be invoked from the __salt__ dunder
|
||||
# in Salt code, this function is only being left here for backwards
|
||||
# compatibility.
|
||||
return salt.utils.normalize_mode(mode)
|
||||
return salt.utils.files.normalize_mode(mode)
|
||||
|
||||
|
||||
def valid_fileproto(uri):
|
||||
|
@ -215,16 +216,16 @@ def get(key, default=u''):
|
|||
|
||||
salt '*' config.get pkg:apache
|
||||
'''
|
||||
ret = salt.utils.traverse_dict_and_list(__opts__, key, u'_|-')
|
||||
ret = salt.utils.data.traverse_dict_and_list(__opts__, key, u'_|-')
|
||||
if ret != u'_|-':
|
||||
return ret
|
||||
ret = salt.utils.traverse_dict_and_list(__grains__, key, u'_|-')
|
||||
ret = salt.utils.data.traverse_dict_and_list(__grains__, key, u'_|-')
|
||||
if ret != u'_|-':
|
||||
return ret
|
||||
ret = salt.utils.traverse_dict_and_list(__pillar__, key, u'_|-')
|
||||
ret = salt.utils.data.traverse_dict_and_list(__pillar__, key, u'_|-')
|
||||
if ret != u'_|-':
|
||||
return ret
|
||||
ret = salt.utils.traverse_dict_and_list(__pillar__.get(u'master', {}), key, u'_|-')
|
||||
ret = salt.utils.data.traverse_dict_and_list(__pillar__.get(u'master', {}), key, u'_|-')
|
||||
if ret != u'_|-':
|
||||
return ret
|
||||
return default
|
||||
|
|
|
@ -11,7 +11,7 @@ import math
|
|||
import json
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
import salt.utils.data
|
||||
import salt.utils.dictupdate
|
||||
from salt.defaults import DEFAULT_TARGET_DELIM
|
||||
from salt.exceptions import SaltException
|
||||
|
@ -75,10 +75,11 @@ def get(key, default=u'', delimiter=DEFAULT_TARGET_DELIM, ordered=True):
|
|||
grains = __grains__
|
||||
else:
|
||||
grains = json.loads(json.dumps(__grains__))
|
||||
return salt.utils.traverse_dict_and_list(__grains__,
|
||||
key,
|
||||
default,
|
||||
delimiter)
|
||||
return salt.utils.data.traverse_dict_and_list(
|
||||
__grains__,
|
||||
key,
|
||||
default,
|
||||
delimiter)
|
||||
|
||||
|
||||
def has_value(key):
|
||||
|
@ -99,7 +100,9 @@ def has_value(key):
|
|||
|
||||
salt '*' grains.has_value pkg:apache
|
||||
'''
|
||||
return True if salt.utils.traverse_dict_and_list(__grains__, key, False) else False
|
||||
return True \
|
||||
if salt.utils.data.traverse_dict_and_list(__grains__, key, False) \
|
||||
else False
|
||||
|
||||
|
||||
def items(sanitize=False):
|
||||
|
@ -118,7 +121,7 @@ def items(sanitize=False):
|
|||
|
||||
salt '*' grains.items sanitize=True
|
||||
'''
|
||||
if salt.utils.is_true(sanitize):
|
||||
if salt.utils.data.is_true(sanitize):
|
||||
out = dict(__grains__)
|
||||
for key, func in six.iteritems(_SANITIZERS):
|
||||
if key in out:
|
||||
|
@ -151,7 +154,7 @@ def item(*args, **kwargs):
|
|||
ret[arg] = __grains__[arg]
|
||||
except KeyError:
|
||||
pass
|
||||
if salt.utils.is_true(kwargs.get(u'sanitize')):
|
||||
if salt.utils.data.is_true(kwargs.get(u'sanitize')):
|
||||
for arg, func in six.iteritems(_SANITIZERS):
|
||||
if arg in ret:
|
||||
ret[arg] = func(ret[arg])
|
||||
|
|
|
@ -9,7 +9,8 @@ import collections
|
|||
|
||||
# Import salt libs
|
||||
import salt.pillar
|
||||
import salt.utils
|
||||
import salt.utils.data
|
||||
import salt.utils.dictupdate
|
||||
from salt.defaults import DEFAULT_TARGET_DELIM
|
||||
|
||||
|
||||
|
@ -51,15 +52,16 @@ def get(key, default=u'', merge=False, delimiter=DEFAULT_TARGET_DELIM):
|
|||
salt '*' pillar.get pkg:apache
|
||||
'''
|
||||
if merge:
|
||||
ret = salt.utils.traverse_dict_and_list(__pillar__, key, {}, delimiter)
|
||||
ret = salt.utils.data.traverse_dict_and_list(__pillar__, key, {}, delimiter)
|
||||
if isinstance(ret, collections.Mapping) and \
|
||||
isinstance(default, collections.Mapping):
|
||||
return salt.utils.dictupdate.update(default, ret)
|
||||
|
||||
return salt.utils.traverse_dict_and_list(__pillar__,
|
||||
key,
|
||||
default,
|
||||
delimiter)
|
||||
return salt.utils.data.traverse_dict_and_list(
|
||||
__pillar__,
|
||||
key,
|
||||
default,
|
||||
delimiter)
|
||||
|
||||
|
||||
def item(*args):
|
||||
|
@ -126,7 +128,7 @@ def keys(key, delimiter=DEFAULT_TARGET_DELIM):
|
|||
|
||||
salt '*' pillar.keys web:sites
|
||||
'''
|
||||
ret = salt.utils.traverse_dict_and_list(
|
||||
ret = salt.utils.data.traverse_dict_and_list(
|
||||
__pillar__, key, KeyError, delimiter)
|
||||
|
||||
if ret is KeyError:
|
||||
|
|
|
@ -13,7 +13,9 @@ import logging
|
|||
# Import salt libs
|
||||
import salt.client.ssh.shell
|
||||
import salt.client.ssh.state
|
||||
import salt.utils
|
||||
import salt.utils.args
|
||||
import salt.utils.data
|
||||
import salt.utils.hashutils
|
||||
import salt.utils.thin
|
||||
import salt.roster
|
||||
import salt.state
|
||||
|
@ -100,7 +102,7 @@ def sls(mods, saltenv=u'base', test=None, exclude=None, **kwargs):
|
|||
__pillar__,
|
||||
st_kwargs[u'id_'],
|
||||
roster_grains)
|
||||
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
cmd = u'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
|
||||
__opts__[u'thin_dir'],
|
||||
test,
|
||||
|
@ -125,7 +127,7 @@ def sls(mods, saltenv=u'base', test=None, exclude=None, **kwargs):
|
|||
|
||||
# Read in the JSON data and return the data structure
|
||||
try:
|
||||
return json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
return json.loads(stdout, object_hook=salt.utils.data.decode_dict)
|
||||
except Exception as e:
|
||||
log.error(u"JSON Render failed for: %s\n%s", stdout, stderr)
|
||||
log.error(str(e))
|
||||
|
@ -177,7 +179,7 @@ def low(data, **kwargs):
|
|||
__pillar__,
|
||||
st_kwargs[u'id_'],
|
||||
roster_grains)
|
||||
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
cmd = u'state.pkg {0}/salt_state.tgz pkg_sum={1} hash_type={2}'.format(
|
||||
__opts__[u'thin_dir'],
|
||||
trans_tar_sum,
|
||||
|
@ -201,7 +203,7 @@ def low(data, **kwargs):
|
|||
|
||||
# Read in the JSON data and return the data structure
|
||||
try:
|
||||
return json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
return json.loads(stdout, object_hook=salt.utils.data.decode_dict)
|
||||
except Exception as e:
|
||||
log.error(u"JSON Render failed for: %s\n%s", stdout, stderr)
|
||||
log.error(str(e))
|
||||
|
@ -250,7 +252,7 @@ def high(data, **kwargs):
|
|||
__pillar__,
|
||||
st_kwargs[u'id_'],
|
||||
roster_grains)
|
||||
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
cmd = u'state.pkg {0}/salt_state.tgz pkg_sum={1} hash_type={2}'.format(
|
||||
__opts__[u'thin_dir'],
|
||||
trans_tar_sum,
|
||||
|
@ -274,7 +276,7 @@ def high(data, **kwargs):
|
|||
|
||||
# Read in the JSON data and return the data structure
|
||||
try:
|
||||
return json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
return json.loads(stdout, object_hook=salt.utils.data.decode_dict)
|
||||
except Exception as e:
|
||||
log.error(u"JSON Render failed for: %s\n%s", stdout, stderr)
|
||||
log.error(str(e))
|
||||
|
@ -353,7 +355,7 @@ def highstate(test=None, **kwargs):
|
|||
__pillar__,
|
||||
st_kwargs[u'id_'],
|
||||
roster_grains)
|
||||
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
cmd = u'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
|
||||
__opts__[u'thin_dir'],
|
||||
test,
|
||||
|
@ -378,7 +380,7 @@ def highstate(test=None, **kwargs):
|
|||
|
||||
# Read in the JSON data and return the data structure
|
||||
try:
|
||||
return json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
return json.loads(stdout, object_hook=salt.utils.data.decode_dict)
|
||||
except Exception as e:
|
||||
log.error(u"JSON Render failed for: %s\n%s", stdout, stderr)
|
||||
log.error(str(e))
|
||||
|
@ -402,7 +404,7 @@ def top(topfn, test=None, **kwargs):
|
|||
__pillar__.update(kwargs.get(u'pillar', {}))
|
||||
st_kwargs = __salt__.kwargs
|
||||
__opts__[u'grains'] = __grains__
|
||||
if salt.utils.test_mode(test=test, **kwargs):
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
__opts__[u'test'] = True
|
||||
else:
|
||||
__opts__[u'test'] = __opts__.get(u'test', None)
|
||||
|
@ -433,7 +435,7 @@ def top(topfn, test=None, **kwargs):
|
|||
__pillar__,
|
||||
st_kwargs[u'id_'],
|
||||
roster_grains)
|
||||
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
cmd = u'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
|
||||
__opts__[u'thin_dir'],
|
||||
test,
|
||||
|
@ -458,7 +460,7 @@ def top(topfn, test=None, **kwargs):
|
|||
|
||||
# Read in the JSON data and return the data structure
|
||||
try:
|
||||
return json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
return json.loads(stdout, object_hook=salt.utils.data.decode_dict)
|
||||
except Exception as e:
|
||||
log.error(u"JSON Render failed for: %s\n%s", stdout, stderr)
|
||||
log.error(str(e))
|
||||
|
@ -519,7 +521,7 @@ def show_sls(mods, saltenv=u'base', test=None, **kwargs):
|
|||
__pillar__.update(kwargs.get(u'pillar', {}))
|
||||
__opts__[u'grains'] = __grains__
|
||||
opts = copy.copy(__opts__)
|
||||
if salt.utils.test_mode(test=test, **kwargs):
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
opts[u'test'] = True
|
||||
else:
|
||||
opts[u'test'] = __opts__.get(u'test', None)
|
||||
|
@ -562,7 +564,7 @@ def show_low_sls(mods, saltenv=u'base', test=None, **kwargs):
|
|||
__opts__[u'grains'] = __grains__
|
||||
|
||||
opts = copy.copy(__opts__)
|
||||
if salt.utils.test_mode(test=test, **kwargs):
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
opts[u'test'] = True
|
||||
else:
|
||||
opts[u'test'] = __opts__.get(u'test', None)
|
||||
|
@ -651,7 +653,7 @@ def single(fun, name, test=None, **kwargs):
|
|||
opts = copy.deepcopy(__opts__)
|
||||
|
||||
# Set test mode
|
||||
if salt.utils.test_mode(test=test, **kwargs):
|
||||
if salt.utils.args.test_mode(test=test, **kwargs):
|
||||
opts[u'test'] = True
|
||||
else:
|
||||
opts[u'test'] = __opts__.get(u'test', None)
|
||||
|
@ -695,7 +697,7 @@ def single(fun, name, test=None, **kwargs):
|
|||
roster_grains)
|
||||
|
||||
# Create a hash so we can verify the tar on the target system
|
||||
trans_tar_sum = salt.utils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
trans_tar_sum = salt.utils.hashutils.get_hash(trans_tar, __opts__[u'hash_type'])
|
||||
|
||||
# We use state.pkg to execute the "state package"
|
||||
cmd = u'state.pkg {0}/salt_state.tgz test={1} pkg_sum={2} hash_type={3}'.format(
|
||||
|
@ -728,7 +730,7 @@ def single(fun, name, test=None, **kwargs):
|
|||
|
||||
# Read in the JSON data and return the data structure
|
||||
try:
|
||||
return json.loads(stdout, object_hook=salt.utils.decode_dict)
|
||||
return json.loads(stdout, object_hook=salt.utils.data.decode_dict)
|
||||
except Exception as e:
|
||||
log.error(u"JSON Render failed for: %s\n%s", stdout, stderr)
|
||||
log.error(str(e))
|
||||
|
|
|
@ -29,10 +29,11 @@ from salt.exceptions import (
|
|||
import salt.config
|
||||
import salt.client
|
||||
import salt.loader
|
||||
import salt.utils
|
||||
import salt.utils.args
|
||||
import salt.utils.cloud
|
||||
import salt.utils.context
|
||||
import salt.utils.crypt
|
||||
import salt.utils.data
|
||||
import salt.utils.dictupdate
|
||||
import salt.utils.files
|
||||
import salt.syspaths
|
||||
|
@ -233,7 +234,7 @@ class CloudClient(object):
|
|||
if a.get('provider', '')]
|
||||
if providers:
|
||||
_providers = opts.get('providers', {})
|
||||
for provider in list(_providers):
|
||||
for provider in list(_providers).copy():
|
||||
if provider not in providers:
|
||||
_providers.pop(provider)
|
||||
return opts
|
||||
|
@ -243,7 +244,7 @@ class CloudClient(object):
|
|||
Pass the cloud function and low data structure to run
|
||||
'''
|
||||
l_fun = getattr(self, fun)
|
||||
f_call = salt.utils.format_call(l_fun, low)
|
||||
f_call = salt.utils.args.format_call(l_fun, low)
|
||||
return l_fun(*f_call.get('args', ()), **f_call.get('kwargs', {}))
|
||||
|
||||
def list_sizes(self, provider=None):
|
||||
|
@ -251,7 +252,7 @@ class CloudClient(object):
|
|||
List all available sizes in configured cloud systems
|
||||
'''
|
||||
mapper = salt.cloud.Map(self._opts_defaults())
|
||||
return salt.utils.simple_types_filter(
|
||||
return salt.utils.data.simple_types_filter(
|
||||
mapper.size_list(provider)
|
||||
)
|
||||
|
||||
|
@ -260,7 +261,7 @@ class CloudClient(object):
|
|||
List all available images in configured cloud systems
|
||||
'''
|
||||
mapper = salt.cloud.Map(self._opts_defaults())
|
||||
return salt.utils.simple_types_filter(
|
||||
return salt.utils.data.simple_types_filter(
|
||||
mapper.image_list(provider)
|
||||
)
|
||||
|
||||
|
@ -269,7 +270,7 @@ class CloudClient(object):
|
|||
List all available locations in configured cloud systems
|
||||
'''
|
||||
mapper = salt.cloud.Map(self._opts_defaults())
|
||||
return salt.utils.simple_types_filter(
|
||||
return salt.utils.data.simple_types_filter(
|
||||
mapper.location_list(provider)
|
||||
)
|
||||
|
||||
|
@ -343,7 +344,7 @@ class CloudClient(object):
|
|||
mapper = salt.cloud.Map(self._opts_defaults(**kwargs))
|
||||
if isinstance(names, six.string_types):
|
||||
names = names.split(',')
|
||||
return salt.utils.simple_types_filter(
|
||||
return salt.utils.data.simple_types_filter(
|
||||
mapper.run_profile(profile, names, vm_overrides=vm_overrides)
|
||||
)
|
||||
|
||||
|
@ -357,7 +358,7 @@ class CloudClient(object):
|
|||
kwarg.update(kwargs)
|
||||
mapper = salt.cloud.Map(self._opts_defaults(**kwarg))
|
||||
dmap = mapper.map_data()
|
||||
return salt.utils.simple_types_filter(
|
||||
return salt.utils.data.simple_types_filter(
|
||||
mapper.run_map(dmap)
|
||||
)
|
||||
|
||||
|
@ -368,7 +369,7 @@ class CloudClient(object):
|
|||
mapper = salt.cloud.Map(self._opts_defaults(destroy=True))
|
||||
if isinstance(names, six.string_types):
|
||||
names = names.split(',')
|
||||
return salt.utils.simple_types_filter(
|
||||
return salt.utils.data.simple_types_filter(
|
||||
mapper.destroy(names)
|
||||
)
|
||||
|
||||
|
@ -407,7 +408,7 @@ class CloudClient(object):
|
|||
vm_['profile'] = None
|
||||
vm_['provider'] = provider
|
||||
|
||||
ret[name] = salt.utils.simple_types_filter(
|
||||
ret[name] = salt.utils.data.simple_types_filter(
|
||||
mapper.create(vm_))
|
||||
return ret
|
||||
|
||||
|
@ -442,7 +443,7 @@ class CloudClient(object):
|
|||
extra_['provider'] = provider
|
||||
extra_['profile'] = None
|
||||
extra_['action'] = action
|
||||
ret[name] = salt.utils.simple_types_filter(
|
||||
ret[name] = salt.utils.data.simple_types_filter(
|
||||
mapper.extras(extra_)
|
||||
)
|
||||
return ret
|
||||
|
@ -1416,7 +1417,7 @@ class Cloud(object):
|
|||
if name in vms:
|
||||
prov = vms[name]['provider']
|
||||
driv = vms[name]['driver']
|
||||
msg = six.u('{0} already exists under {1}:{2}').format(
|
||||
msg = u'{0} already exists under {1}:{2}'.format(
|
||||
name, prov, driv
|
||||
)
|
||||
log.error(msg)
|
||||
|
@ -2098,7 +2099,7 @@ class Map(Cloud):
|
|||
master_temp_pub = salt.utils.files.mkstemp()
|
||||
with salt.utils.files.fopen(master_temp_pub, 'w') as mtp:
|
||||
mtp.write(pub)
|
||||
master_finger = salt.utils.pem_finger(master_temp_pub, sum_type=self.opts['hash_type'])
|
||||
master_finger = salt.utils.crypt.pem_finger(master_temp_pub, sum_type=self.opts['hash_type'])
|
||||
os.unlink(master_temp_pub)
|
||||
|
||||
if master_profile.get('make_minion', True) is True:
|
||||
|
@ -2183,7 +2184,7 @@ class Map(Cloud):
|
|||
# mitigate man-in-the-middle attacks
|
||||
master_pub = os.path.join(self.opts['pki_dir'], 'master.pub')
|
||||
if os.path.isfile(master_pub):
|
||||
master_finger = salt.utils.pem_finger(master_pub, sum_type=self.opts['hash_type'])
|
||||
master_finger = salt.utils.crypt.pem_finger(master_pub, sum_type=self.opts['hash_type'])
|
||||
|
||||
opts = self.opts.copy()
|
||||
if self.opts['parallel']:
|
||||
|
@ -2300,7 +2301,7 @@ def create_multiprocessing(parallel_data, queue=None):
|
|||
This function will be called from another process when running a map in
|
||||
parallel mode. The result from the create is always a json object.
|
||||
'''
|
||||
salt.utils.reinit_crypto()
|
||||
salt.utils.crypt.reinit_crypto()
|
||||
|
||||
parallel_data['opts']['output'] = 'json'
|
||||
cloud = Cloud(parallel_data['opts'])
|
||||
|
@ -2323,7 +2324,7 @@ def create_multiprocessing(parallel_data, queue=None):
|
|||
output.pop('deploy_kwargs', None)
|
||||
|
||||
return {
|
||||
parallel_data['name']: salt.utils.simple_types_filter(output)
|
||||
parallel_data['name']: salt.utils.data.simple_types_filter(output)
|
||||
}
|
||||
|
||||
|
||||
|
@ -2332,7 +2333,7 @@ def destroy_multiprocessing(parallel_data, queue=None):
|
|||
This function will be called from another process when running a map in
|
||||
parallel mode. The result from the destroy is always a json object.
|
||||
'''
|
||||
salt.utils.reinit_crypto()
|
||||
salt.utils.crypt.reinit_crypto()
|
||||
|
||||
parallel_data['opts']['output'] = 'json'
|
||||
clouds = salt.loader.clouds(parallel_data['opts'])
|
||||
|
@ -2359,7 +2360,7 @@ def destroy_multiprocessing(parallel_data, queue=None):
|
|||
return {parallel_data['name']: {'Error': str(exc)}}
|
||||
|
||||
return {
|
||||
parallel_data['name']: salt.utils.simple_types_filter(output)
|
||||
parallel_data['name']: salt.utils.data.simple_types_filter(output)
|
||||
}
|
||||
|
||||
|
||||
|
@ -2368,7 +2369,7 @@ def run_parallel_map_providers_query(data, queue=None):
|
|||
This function will be called from another process when building the
|
||||
providers map.
|
||||
'''
|
||||
salt.utils.reinit_crypto()
|
||||
salt.utils.crypt.reinit_crypto()
|
||||
|
||||
cloud = Cloud(data['opts'])
|
||||
try:
|
||||
|
@ -2382,7 +2383,7 @@ def run_parallel_map_providers_query(data, queue=None):
|
|||
return (
|
||||
data['alias'],
|
||||
data['driver'],
|
||||
salt.utils.simple_types_filter(
|
||||
salt.utils.data.simple_types_filter(
|
||||
cloud.clouds[data['fun']]()
|
||||
)
|
||||
)
|
||||
|
|
|
@ -42,6 +42,7 @@ from salt.ext.six.moves.urllib.parse import quote as _quote # pylint: disable=i
|
|||
|
||||
# Import salt cloud libs
|
||||
import salt.utils.cloud
|
||||
import salt.utils.data
|
||||
import salt.config as config
|
||||
from salt.exceptions import (
|
||||
SaltCloudNotFound,
|
||||
|
@ -823,7 +824,7 @@ def query(params=None):
|
|||
|
||||
content = request.text
|
||||
|
||||
result = json.loads(content, object_hook=salt.utils.decode_dict)
|
||||
result = json.loads(content, object_hook=salt.utils.data.decode_dict)
|
||||
if 'Code' in result:
|
||||
raise SaltCloudSystemExit(
|
||||
pprint.pformat(result.get('Message', {}))
|
||||
|
|
|
@ -10,6 +10,7 @@ The Azure cloud module is used to control access to Microsoft Azure
|
|||
:depends:
|
||||
* `Microsoft Azure SDK for Python <https://pypi.python.org/pypi/azure>`_ >= 2.0rc5
|
||||
* `Microsoft Azure Storage SDK for Python <https://pypi.python.org/pypi/azure-storage>`_ >= 0.32
|
||||
* `Microsoft Azure CLI <https://pypi.python.org/pypi/azure-cli>` >= 2.0.12
|
||||
:configuration:
|
||||
Required provider parameters:
|
||||
|
||||
|
@ -62,8 +63,8 @@ import yaml
|
|||
import collections
|
||||
import salt.cache
|
||||
import salt.config as config
|
||||
import salt.utils
|
||||
import salt.utils.cloud
|
||||
import salt.utils.data
|
||||
import salt.utils.files
|
||||
from salt.utils.versions import LooseVersion
|
||||
from salt.ext import six
|
||||
|
@ -146,7 +147,13 @@ def __virtual__():
|
|||
return False
|
||||
|
||||
if get_dependencies() is False:
|
||||
return False
|
||||
return (
|
||||
False,
|
||||
'The following dependencies are required to use the AzureARM driver: '
|
||||
'Microsoft Azure SDK for Python >= 2.0rc5, '
|
||||
'Microsoft Azure Storage SDK for Python >= 0.32, '
|
||||
'Microsoft Azure CLI >= 2.0.12'
|
||||
)
|
||||
|
||||
global cache # pylint: disable=global-statement,invalid-name
|
||||
cache = salt.cache.Cache(__opts__)
|
||||
|
@ -568,7 +575,7 @@ def show_instance(name, resource_group=None, call=None): # pylint: disable=unus
|
|||
data['resource_group'] = resource_group
|
||||
|
||||
__utils__['cloud.cache_node'](
|
||||
salt.utils.simple_types_filter(data),
|
||||
salt.utils.data.simple_types_filter(data),
|
||||
__active_provider_name__,
|
||||
__opts__
|
||||
)
|
||||
|
@ -1453,7 +1460,7 @@ def make_safe(data):
|
|||
'''
|
||||
Turn object data into something serializable
|
||||
'''
|
||||
return salt.utils.simple_types_filter(object_to_dict(data))
|
||||
return salt.utils.data.simple_types_filter(object_to_dict(data))
|
||||
|
||||
|
||||
def create_security_group(call=None, kwargs=None): # pylint: disable=unused-argument
|
||||
|
|
371
salt/cloud/clouds/clc.py
Normal file
371
salt/cloud/clouds/clc.py
Normal file
|
@ -0,0 +1,371 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
'''
|
||||
CenturyLink Cloud Module
|
||||
===================
|
||||
|
||||
.. versionadded:: 0yxgen
|
||||
|
||||
The CLC cloud module allows you to manage CLC Via the CLC SDK.
|
||||
|
||||
:codeauthor: Stephan Looney <slooney@stephanlooney.com>
|
||||
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
- clc-sdk Python Module
|
||||
- flask
|
||||
|
||||
CLC SDK
|
||||
-------
|
||||
|
||||
clc-sdk can be installed via pip:
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
pip install clc-sdk
|
||||
|
||||
.. note::
|
||||
For sdk reference see: https://github.com/CenturyLinkCloud/clc-python-sdk
|
||||
|
||||
Flask
|
||||
-------
|
||||
flask can be installed via pip:
|
||||
.. code-block:: bash
|
||||
pip install flask
|
||||
|
||||
Configuration
|
||||
=============
|
||||
|
||||
To use this module: set up the clc-sdk, user, password, key in the
|
||||
cloud configuration at
|
||||
``/etc/salt/cloud.providers`` or ``/etc/salt/cloud.providers.d/clc.conf``:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
my-clc-config:
|
||||
driver: clc
|
||||
user: 'web-user'
|
||||
password: 'verybadpass'
|
||||
token: ''
|
||||
token_pass:''
|
||||
accountalias: 'ACT'
|
||||
.. note::
|
||||
|
||||
The ``provider`` parameter in cloud provider configuration was renamed to ``driver``.
|
||||
This change was made to avoid confusion with the ``provider`` parameter that is
|
||||
used in cloud profile configuration. Cloud provider configuration now uses ``driver``
|
||||
to refer to the salt-cloud driver that provides the underlying functionality to
|
||||
connect to a cloud provider, while cloud profile configuration continues to use
|
||||
``provider`` to refer to the cloud provider configuration that you define.
|
||||
|
||||
'''
|
||||
|
||||
# Import python libs
|
||||
from __future__ import absolute_import
|
||||
import logging
|
||||
import time
|
||||
import json
|
||||
# Import salt libs
|
||||
import importlib
|
||||
from salt.exceptions import SaltCloudSystemExit
|
||||
# Import salt cloud libs
|
||||
import salt.config as config
|
||||
|
||||
# Get logging started
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
# Attempt to import clc-sdk lib
|
||||
try:
|
||||
#when running this in linode's Ubuntu 16.x version the following line is required to get the clc sdk libraries to load
|
||||
importlib.import_module('clc')
|
||||
import clc
|
||||
HAS_CLC = True
|
||||
except ImportError:
|
||||
HAS_CLC = False
|
||||
# Disable InsecureRequestWarning generated on python > 2.6
|
||||
try:
|
||||
from requests.packages.urllib3 import disable_warnings # pylint: disable=no-name-in-module
|
||||
disable_warnings()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
|
||||
__virtualname__ = 'clc'
|
||||
|
||||
|
||||
# Only load in this module if the CLC configurations are in place
|
||||
def __virtual__():
|
||||
'''
|
||||
Check for CLC configuration and if required libs are available.
|
||||
'''
|
||||
if get_configured_provider() is False or get_dependencies() is False:
|
||||
return False
|
||||
|
||||
return __virtualname__
|
||||
|
||||
|
||||
def get_configured_provider():
|
||||
return config.is_provider_configured(
|
||||
__opts__,
|
||||
__active_provider_name__ or __virtualname__,
|
||||
('token', 'token_pass', 'user', 'password', )
|
||||
)
|
||||
|
||||
|
||||
def get_dependencies():
|
||||
'''
|
||||
Warn if dependencies aren't met.
|
||||
'''
|
||||
deps = {
|
||||
'clc': HAS_CLC,
|
||||
}
|
||||
return config.check_driver_dependencies(
|
||||
__virtualname__,
|
||||
deps
|
||||
)
|
||||
|
||||
|
||||
def get_creds():
|
||||
user = config.get_cloud_config_value(
|
||||
'user', get_configured_provider(), __opts__, search_global=False
|
||||
)
|
||||
password = config.get_cloud_config_value(
|
||||
'password', get_configured_provider(), __opts__, search_global=False
|
||||
)
|
||||
accountalias = config.get_cloud_config_value(
|
||||
'accountalias', get_configured_provider(), __opts__, search_global=False
|
||||
)
|
||||
token = config.get_cloud_config_value(
|
||||
'token', get_configured_provider(), __opts__, search_global=False
|
||||
)
|
||||
token_pass = config.get_cloud_config_value(
|
||||
'token_pass', get_configured_provider(), __opts__, search_global=False
|
||||
)
|
||||
creds = {'user': user, 'password': password, 'token': token, 'token_pass': token_pass, 'accountalias': accountalias}
|
||||
return creds
|
||||
|
||||
|
||||
def list_nodes_full(call=None, for_output=True):
|
||||
'''
|
||||
Return a list of the VMs that are on the provider
|
||||
'''
|
||||
if call == 'action':
|
||||
raise SaltCloudSystemExit(
|
||||
'The list_nodes_full function must be called with -f or --function.'
|
||||
)
|
||||
creds = get_creds()
|
||||
clc.v1.SetCredentials(creds["token"], creds["token_pass"])
|
||||
servers_raw = clc.v1.Server.GetServers(location=None)
|
||||
servers_raw = json.dumps(servers_raw)
|
||||
servers = json.loads(servers_raw)
|
||||
return servers
|
||||
|
||||
|
||||
def get_queue_data(call=None, for_output=True):
|
||||
creds = get_creds()
|
||||
clc.v1.SetCredentials(creds["token"], creds["token_pass"])
|
||||
cl_queue = clc.v1.Queue.List()
|
||||
return cl_queue
|
||||
|
||||
|
||||
def get_monthly_estimate(call=None, for_output=True):
|
||||
'''
|
||||
Return a list of the VMs that are on the provider
|
||||
'''
|
||||
creds = get_creds()
|
||||
clc.v1.SetCredentials(creds["token"], creds["token_pass"])
|
||||
if call == 'action':
|
||||
raise SaltCloudSystemExit(
|
||||
'The list_nodes_full function must be called with -f or --function.'
|
||||
)
|
||||
try:
|
||||
billing_raw = clc.v1.Billing.GetAccountSummary(alias=creds["accountalias"])
|
||||
billing_raw = json.dumps(billing_raw)
|
||||
billing = json.loads(billing_raw)
|
||||
billing = round(billing["MonthlyEstimate"], 2)
|
||||
return {"Monthly Estimate": billing}
|
||||
except RuntimeError:
|
||||
return {"Monthly Estimate": 0}
|
||||
|
||||
|
||||
def get_month_to_date(call=None, for_output=True):
|
||||
'''
|
||||
Return a list of the VMs that are on the provider
|
||||
'''
|
||||
creds = get_creds()
|
||||
clc.v1.SetCredentials(creds["token"], creds["token_pass"])
|
||||
if call == 'action':
|
||||
raise SaltCloudSystemExit(
|
||||
'The list_nodes_full function must be called with -f or --function.'
|
||||
)
|
||||
try:
|
||||
billing_raw = clc.v1.Billing.GetAccountSummary(alias=creds["accountalias"])
|
||||
billing_raw = json.dumps(billing_raw)
|
||||
billing = json.loads(billing_raw)
|
||||
billing = round(billing["MonthToDateTotal"], 2)
|
||||
return {"Month To Date": billing}
|
||||
except RuntimeError:
|
||||
return 0
|
||||
|
||||
|
||||
def get_server_alerts(call=None, for_output=True, **kwargs):
|
||||
'''
|
||||
Return a list of alerts from CLC as reported by their infra
|
||||
'''
|
||||
for key, value in kwargs.items():
|
||||
servername = ""
|
||||
if key == "servername":
|
||||
servername = value
|
||||
creds = get_creds()
|
||||
clc.v2.SetCredentials(creds["user"], creds["password"])
|
||||
alerts = clc.v2.Server(servername).Alerts()
|
||||
return alerts
|
||||
|
||||
|
||||
def get_group_estimate(call=None, for_output=True, **kwargs):
|
||||
'''
|
||||
Return a list of the VMs that are on the provider
|
||||
usage: "salt-cloud -f get_group_estimate clc group=Dev location=VA1"
|
||||
'''
|
||||
for key, value in kwargs.items():
|
||||
group = ""
|
||||
location = ""
|
||||
if key == "group":
|
||||
group = value
|
||||
if key == "location":
|
||||
location = value
|
||||
creds = get_creds()
|
||||
clc.v1.SetCredentials(creds["token"], creds["token_pass"])
|
||||
if call == 'action':
|
||||
raise SaltCloudSystemExit(
|
||||
'The list_nodes_full function must be called with -f or --function.'
|
||||
)
|
||||
try:
|
||||
billing_raw = clc.v1.Billing.GetGroupEstimate(group=group, alias=creds["accountalias"], location=location)
|
||||
billing_raw = json.dumps(billing_raw)
|
||||
billing = json.loads(billing_raw)
|
||||
estimate = round(billing["MonthlyEstimate"], 2)
|
||||
month_to_date = round(billing["MonthToDate"], 2)
|
||||
return {"Monthly Estimate": estimate, "Month to Date": month_to_date}
|
||||
except RuntimeError:
|
||||
return 0
|
||||
|
||||
|
||||
def avail_images(call=None):
|
||||
'''
|
||||
returns a list of images available to you
|
||||
'''
|
||||
all_servers = list_nodes_full()
|
||||
templates = {}
|
||||
for server in all_servers:
|
||||
if server["IsTemplate"]:
|
||||
templates.update({"Template Name": server["Name"]})
|
||||
return templates
|
||||
|
||||
|
||||
def avail_locations(call=None):
|
||||
'''
|
||||
returns a list of locations available to you
|
||||
'''
|
||||
creds = get_creds()
|
||||
clc.v1.SetCredentials(creds["token"], creds["token_pass"])
|
||||
locations = clc.v1.Account.GetLocations()
|
||||
return locations
|
||||
|
||||
|
||||
def avail_sizes(call=None):
|
||||
'''
|
||||
use templates for this
|
||||
'''
|
||||
return {"Sizes": "Sizes are built into templates. Choose appropriate template"}
|
||||
|
||||
|
||||
def get_build_status(req_id, nodename):
|
||||
'''
|
||||
get the build status from CLC to make sure we dont return to early
|
||||
'''
|
||||
counter = 0
|
||||
req_id = str(req_id)
|
||||
while counter < 10:
|
||||
queue = clc.v1.Blueprint.GetStatus(request_id=(req_id))
|
||||
if queue["PercentComplete"] == 100:
|
||||
server_name = queue["Servers"][0]
|
||||
creds = get_creds()
|
||||
clc.v2.SetCredentials(creds["user"], creds["password"])
|
||||
ip_addresses = clc.v2.Server(server_name).ip_addresses
|
||||
internal_ip_address = ip_addresses[0]["internal"]
|
||||
return internal_ip_address
|
||||
else:
|
||||
counter = counter + 1
|
||||
log.info("Creating Cloud VM " + nodename + " Time out in " + str(10 - counter) + " minutes")
|
||||
time.sleep(60)
|
||||
|
||||
|
||||
def create(vm_):
|
||||
'''
|
||||
get the system build going
|
||||
'''
|
||||
creds = get_creds()
|
||||
clc.v1.SetCredentials(creds["token"], creds["token_pass"])
|
||||
cloud_profile = config.is_provider_configured(
|
||||
__opts__,
|
||||
__active_provider_name__ or __virtualname__,
|
||||
('token',)
|
||||
)
|
||||
group = config.get_cloud_config_value(
|
||||
'group', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
name = vm_['name']
|
||||
description = config.get_cloud_config_value(
|
||||
'description', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
ram = config.get_cloud_config_value(
|
||||
'ram', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
backup_level = config.get_cloud_config_value(
|
||||
'backup_level', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
template = config.get_cloud_config_value(
|
||||
'template', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
password = config.get_cloud_config_value(
|
||||
'password', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
cpu = config.get_cloud_config_value(
|
||||
'cpu', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
network = config.get_cloud_config_value(
|
||||
'network', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
location = config.get_cloud_config_value(
|
||||
'location', vm_, __opts__, search_global=False, default=None,
|
||||
)
|
||||
if len(name) > 6:
|
||||
name = name[0:6]
|
||||
if len(password) < 9:
|
||||
password = ''
|
||||
clc_return = clc.v1.Server.Create(alias=None, location=(location), name=(name), template=(template), cpu=(cpu), ram=(ram), backup_level=(backup_level), group=(group), network=(network), description=(description), password=(password))
|
||||
req_id = clc_return["RequestID"]
|
||||
vm_['ssh_host'] = get_build_status(req_id, name)
|
||||
__utils__['cloud.fire_event'](
|
||||
'event',
|
||||
'waiting for ssh',
|
||||
'salt/cloud/{0}/waiting_for_ssh'.format(name),
|
||||
sock_dir=__opts__['sock_dir'],
|
||||
args={'ip_address': vm_['ssh_host']},
|
||||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
# Bootstrap!
|
||||
ret = __utils__['cloud.bootstrap'](vm_, __opts__)
|
||||
return_message = {"Server Name": name, "IP Address": vm_['ssh_host']}
|
||||
ret.update(return_message)
|
||||
return return_message
|
||||
|
||||
|
||||
def destroy(name, call=None):
|
||||
'''
|
||||
destroy the vm
|
||||
'''
|
||||
return {"status": "destroying must be done via https://control.ctl.io at this time"}
|
|
@ -33,7 +33,7 @@ import salt.config as config
|
|||
import salt.utils.cloud
|
||||
import salt.utils.event
|
||||
from salt.cloud.libcloudfuncs import * # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import
|
||||
from salt.utils import namespaced_function
|
||||
from salt.utils.functools import namespaced_function
|
||||
from salt.exceptions import SaltCloudSystemExit
|
||||
from salt.utils.versions import LooseVersion as _LooseVersion
|
||||
|
||||
|
|
|
@ -298,7 +298,8 @@ def create(vm_):
|
|||
'size': get_size(vm_),
|
||||
'image': get_image(vm_),
|
||||
'region': get_location(vm_),
|
||||
'ssh_keys': []
|
||||
'ssh_keys': [],
|
||||
'tags': []
|
||||
}
|
||||
|
||||
# backwards compat
|
||||
|
@ -379,6 +380,10 @@ def create(vm_):
|
|||
raise SaltCloudConfigError("'ipv6' should be a boolean value.")
|
||||
kwargs['ipv6'] = ipv6
|
||||
|
||||
kwargs['tags'] = config.get_cloud_config_value(
|
||||
'tags', vm_, __opts__, search_global=False, default=False
|
||||
)
|
||||
|
||||
userdata_file = config.get_cloud_config_value(
|
||||
'userdata_file', vm_, __opts__, search_global=False, default=None
|
||||
)
|
||||
|
|
|
@ -55,12 +55,9 @@ except ImportError:
|
|||
# Import generic libcloud functions
|
||||
# from salt.cloud.libcloudfuncs import *
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
# Import salt.cloud libs
|
||||
from salt.cloud.libcloudfuncs import * # pylint: disable=redefined-builtin,wildcard-import,unused-wildcard-import
|
||||
from salt.utils import namespaced_function
|
||||
from salt.utils.functools import namespaced_function
|
||||
import salt.utils.cloud
|
||||
import salt.config as config
|
||||
from salt.exceptions import (
|
||||
|
|
|
@ -82,7 +82,7 @@ except ImportError:
|
|||
# pylint: enable=import-error
|
||||
|
||||
# Import salt libs
|
||||
from salt.utils import namespaced_function
|
||||
from salt.utils.functools import namespaced_function
|
||||
from salt.ext import six
|
||||
import salt.utils.cloud
|
||||
import salt.utils.files
|
||||
|
@ -2080,6 +2080,7 @@ def attach_disk(name=None, kwargs=None, call=None):
|
|||
disk_name = kwargs['disk_name']
|
||||
mode = kwargs.get('mode', 'READ_WRITE').upper()
|
||||
boot = kwargs.get('boot', False)
|
||||
auto_delete = kwargs.get('auto_delete', False)
|
||||
if boot and boot.lower() in ['true', 'yes', 'enabled']:
|
||||
boot = True
|
||||
else:
|
||||
|
@ -2109,7 +2110,8 @@ def attach_disk(name=None, kwargs=None, call=None):
|
|||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
result = conn.attach_volume(node, disk, ex_mode=mode, ex_boot=boot)
|
||||
result = conn.attach_volume(node, disk, ex_mode=mode, ex_boot=boot,
|
||||
ex_auto_delete=auto_delete)
|
||||
|
||||
__utils__['cloud.fire_event'](
|
||||
'event',
|
||||
|
@ -2389,6 +2391,8 @@ def create_attach_volumes(name, kwargs, call=None):
|
|||
'type': The disk type, either pd-standard or pd-ssd. Optional, defaults to pd-standard.
|
||||
'image': An image to use for this new disk. Optional.
|
||||
'snapshot': A snapshot to use for this new disk. Optional.
|
||||
'auto_delete': An option(bool) to keep or remove the disk upon
|
||||
instance deletion. Optional, defaults to False.
|
||||
|
||||
Volumes are attached in the order in which they are given, thus on a new
|
||||
node the first volume will be /dev/sdb, the second /dev/sdc, and so on.
|
||||
|
@ -2401,9 +2405,10 @@ def create_attach_volumes(name, kwargs, call=None):
|
|||
'-a or --action.'
|
||||
)
|
||||
|
||||
volumes = kwargs['volumes']
|
||||
volumes = literal_eval(kwargs['volumes'])
|
||||
node = kwargs['node']
|
||||
node_data = _expand_node(node)
|
||||
conn = get_conn()
|
||||
node_data = _expand_node(conn.ex_get_node(node))
|
||||
letter = ord('a') - 1
|
||||
|
||||
for idx, volume in enumerate(volumes):
|
||||
|
@ -2413,9 +2418,10 @@ def create_attach_volumes(name, kwargs, call=None):
|
|||
'disk_name': volume_name,
|
||||
'location': node_data['extra']['zone']['name'],
|
||||
'size': volume['size'],
|
||||
'type': volume['type'],
|
||||
'image': volume['image'],
|
||||
'snapshot': volume['snapshot']
|
||||
'type': volume.get('type', 'pd-standard'),
|
||||
'image': volume.get('image', None),
|
||||
'snapshot': volume.get('snapshot', None),
|
||||
'auto_delete': volume.get('auto_delete', False)
|
||||
}
|
||||
|
||||
create_disk(volume_dict, 'function')
|
||||
|
@ -2581,7 +2587,10 @@ def create(vm_=None, call=None):
|
|||
ssh_user, ssh_key = __get_ssh_credentials(vm_)
|
||||
vm_['ssh_host'] = __get_host(node_data, vm_)
|
||||
vm_['key_filename'] = ssh_key
|
||||
__utils__['cloud.bootstrap'](vm_, __opts__)
|
||||
|
||||
ret = __utils__['cloud.bootstrap'](vm_, __opts__)
|
||||
|
||||
ret.update(node_dict)
|
||||
|
||||
log.info('Created Cloud VM \'{0[name]}\''.format(vm_))
|
||||
log.trace(
|
||||
|
@ -2599,7 +2608,7 @@ def create(vm_=None, call=None):
|
|||
transport=__opts__['transport']
|
||||
)
|
||||
|
||||
return node_dict
|
||||
return ret
|
||||
|
||||
|
||||
def update_pricing(kwargs=None, call=None):
|
||||
|
|
|
@ -74,7 +74,6 @@ except ImportError:
|
|||
|
||||
# Import salt libs
|
||||
import salt.config as config
|
||||
import salt.utils
|
||||
import salt.utils.cloud
|
||||
from salt.exceptions import (
|
||||
SaltCloudConfigError,
|
||||
|
@ -466,18 +465,54 @@ def create(vm_):
|
|||
|
||||
return ret
|
||||
except Exception as e: # pylint: disable=broad-except
|
||||
# Try to clean up in as much cases as possible
|
||||
log.info('Cleaning up after exception clean up items: {0}'.format(cleanup))
|
||||
for leftover in cleanup:
|
||||
what = leftover['what']
|
||||
item = leftover['item']
|
||||
if what == 'domain':
|
||||
destroy_domain(conn, item)
|
||||
if what == 'volume':
|
||||
item.delete()
|
||||
do_cleanup(cleanup)
|
||||
# throw the root cause after cleanup
|
||||
raise e
|
||||
|
||||
|
||||
def do_cleanup(cleanup):
|
||||
'''
|
||||
Clean up clone domain leftovers as much as possible.
|
||||
|
||||
Extra robust clean up in order to deal with some small changes in libvirt
|
||||
behavior over time. Passed in volumes and domains are deleted, any errors
|
||||
are ignored. Used when cloning/provisioning a domain fails.
|
||||
|
||||
:param cleanup: list containing dictonaries with two keys: 'what' and 'item'.
|
||||
If 'what' is domain the 'item' is a libvirt domain object.
|
||||
If 'what' is volume then the item is a libvirt volume object.
|
||||
|
||||
Returns:
|
||||
none
|
||||
|
||||
.. versionadded: 2017.7.3
|
||||
'''
|
||||
log.info('Cleaning up after exception')
|
||||
for leftover in cleanup:
|
||||
what = leftover['what']
|
||||
item = leftover['item']
|
||||
if what == 'domain':
|
||||
log.info('Cleaning up {0} {1}'.format(what, item.name()))
|
||||
try:
|
||||
item.destroy()
|
||||
log.debug('{0} {1} forced off'.format(what, item.name()))
|
||||
except libvirtError:
|
||||
pass
|
||||
try:
|
||||
item.undefineFlags(libvirt.VIR_DOMAIN_UNDEFINE_MANAGED_SAVE+
|
||||
libvirt.VIR_DOMAIN_UNDEFINE_SNAPSHOTS_METADATA+
|
||||
libvirt.VIR_DOMAIN_UNDEFINE_NVRAM)
|
||||
log.debug('{0} {1} undefined'.format(what, item.name()))
|
||||
except libvirtError:
|
||||
pass
|
||||
if what == 'volume':
|
||||
try:
|
||||
item.delete()
|
||||
log.debug('{0} {1} cleaned up'.format(what, item.name()))
|
||||
except libvirtError:
|
||||
pass
|
||||
|
||||
|
||||
def destroy(name, call=None):
|
||||
"""
|
||||
This function irreversibly destroys a virtual machine on the cloud provider.
|
||||
|
|
|
@ -17,9 +17,6 @@ import copy
|
|||
import time
|
||||
from pprint import pformat
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils
|
||||
|
||||
# Import salt cloud libs
|
||||
import salt.utils.cloud
|
||||
import salt.config as config
|
||||
|
|
|
@ -223,7 +223,7 @@ except ImportError as exc:
|
|||
# Import Salt Cloud Libs
|
||||
from salt.cloud.libcloudfuncs import * # pylint: disable=W0614,W0401
|
||||
import salt.config as config
|
||||
from salt.utils import namespaced_function
|
||||
from salt.utils.functools import namespaced_function
|
||||
from salt.exceptions import (
|
||||
SaltCloudConfigError,
|
||||
SaltCloudNotFound,
|
||||
|
|
|
@ -76,7 +76,7 @@ from salt.exceptions import (
|
|||
SaltCloudNotFound,
|
||||
SaltCloudSystemExit
|
||||
)
|
||||
import salt.utils
|
||||
import salt.utils.data
|
||||
import salt.utils.files
|
||||
|
||||
# Import Third Party Libs
|
||||
|
@ -1575,7 +1575,7 @@ def image_persistent(call=None, kwargs=None):
|
|||
|
||||
server, user, password = _get_xml_rpc()
|
||||
auth = ':'.join([user, password])
|
||||
response = server.one.image.persistent(auth, int(image_id), salt.utils.is_true(persist))
|
||||
response = server.one.image.persistent(auth, int(image_id), salt.utils.data.is_true(persist))
|
||||
|
||||
data = {
|
||||
'action': 'image.persistent',
|
||||
|
@ -2794,7 +2794,7 @@ def vm_allocate(call=None, kwargs=None):
|
|||
|
||||
server, user, password = _get_xml_rpc()
|
||||
auth = ':'.join([user, password])
|
||||
response = server.one.vm.allocate(auth, data, salt.utils.is_true(hold))
|
||||
response = server.one.vm.allocate(auth, data, salt.utils.data.is_true(hold))
|
||||
|
||||
ret = {
|
||||
'action': 'vm.allocate',
|
||||
|
@ -3026,7 +3026,7 @@ def vm_deploy(name, kwargs=None, call=None):
|
|||
response = server.one.vm.deploy(auth,
|
||||
int(vm_id),
|
||||
int(host_id),
|
||||
salt.utils.is_true(capacity_maintained),
|
||||
salt.utils.data.is_true(capacity_maintained),
|
||||
int(datastore_id))
|
||||
|
||||
data = {
|
||||
|
@ -3495,8 +3495,8 @@ def vm_migrate(name, kwargs=None, call=None):
|
|||
response = server.one.vm.migrate(auth,
|
||||
vm_id,
|
||||
int(host_id),
|
||||
salt.utils.is_true(live_migration),
|
||||
salt.utils.is_true(capacity_maintained),
|
||||
salt.utils.data.is_true(live_migration),
|
||||
salt.utils.data.is_true(capacity_maintained),
|
||||
int(datastore_id))
|
||||
|
||||
data = {
|
||||
|
@ -3615,7 +3615,7 @@ def vm_resize(name, kwargs=None, call=None):
|
|||
server, user, password = _get_xml_rpc()
|
||||
auth = ':'.join([user, password])
|
||||
vm_id = int(get_vm_id(kwargs={'name': name}))
|
||||
response = server.one.vm.resize(auth, vm_id, data, salt.utils.is_true(capacity_maintained))
|
||||
response = server.one.vm.resize(auth, vm_id, data, salt.utils.data.is_true(capacity_maintained))
|
||||
|
||||
ret = {
|
||||
'action': 'vm.resize',
|
||||
|
@ -4572,7 +4572,8 @@ def _list_nodes(full=False):
|
|||
pass
|
||||
|
||||
vms[name]['id'] = vm.find('ID').text
|
||||
vms[name]['image'] = vm.find('TEMPLATE').find('TEMPLATE_ID').text
|
||||
if vm.find('TEMPLATE').find('TEMPLATE_ID'):
|
||||
vms[name]['image'] = vm.find('TEMPLATE').find('TEMPLATE_ID').text
|
||||
vms[name]['name'] = name
|
||||
vms[name]['size'] = {'cpu': cpu_size, 'memory': memory_size}
|
||||
vms[name]['state'] = vm.find('STATE').text
|
||||
|
|
|
@ -185,7 +185,6 @@ except Exception:
|
|||
from salt.cloud.libcloudfuncs import * # pylint: disable=W0614,W0401
|
||||
|
||||
# Import salt libs
|
||||
import salt.utils # Can be removed once namespaced_function has been moved
|
||||
import salt.utils.cloud
|
||||
import salt.utils.files
|
||||
import salt.utils.pycrypto
|
||||
|
@ -197,6 +196,7 @@ from salt.exceptions import (
|
|||
SaltCloudExecutionFailure,
|
||||
SaltCloudExecutionTimeout
|
||||
)
|
||||
from salt.utils.functools import namespaced_function
|
||||
|
||||
# Import netaddr IP matching
|
||||
try:
|
||||
|
@ -214,19 +214,19 @@ __virtualname__ = 'openstack'
|
|||
# Some of the libcloud functions need to be in the same namespace as the
|
||||
# functions defined in the module, so we create new function objects inside
|
||||
# this module namespace
|
||||
get_size = salt.utils.namespaced_function(get_size, globals())
|
||||
get_image = salt.utils.namespaced_function(get_image, globals())
|
||||
avail_locations = salt.utils.namespaced_function(avail_locations, globals())
|
||||
avail_images = salt.utils.namespaced_function(avail_images, globals())
|
||||
avail_sizes = salt.utils.namespaced_function(avail_sizes, globals())
|
||||
script = salt.utils.namespaced_function(script, globals())
|
||||
destroy = salt.utils.namespaced_function(destroy, globals())
|
||||
reboot = salt.utils.namespaced_function(reboot, globals())
|
||||
list_nodes = salt.utils.namespaced_function(list_nodes, globals())
|
||||
list_nodes_full = salt.utils.namespaced_function(list_nodes_full, globals())
|
||||
list_nodes_select = salt.utils.namespaced_function(list_nodes_select, globals())
|
||||
show_instance = salt.utils.namespaced_function(show_instance, globals())
|
||||
get_node = salt.utils.namespaced_function(get_node, globals())
|
||||
get_size = namespaced_function(get_size, globals())
|
||||
get_image = namespaced_function(get_image, globals())
|
||||
avail_locations = namespaced_function(avail_locations, globals())
|
||||
avail_images = namespaced_function(avail_images, globals())
|
||||
avail_sizes = namespaced_function(avail_sizes, globals())
|
||||
script = namespaced_function(script, globals())
|
||||
destroy = namespaced_function(destroy, globals())
|
||||
reboot = namespaced_function(reboot, globals())
|
||||
list_nodes = namespaced_function(list_nodes, globals())
|
||||
list_nodes_full = namespaced_function(list_nodes_full, globals())
|
||||
list_nodes_select = namespaced_function(list_nodes_select, globals())
|
||||
show_instance = namespaced_function(show_instance, globals())
|
||||
get_node = namespaced_function(get_node, globals())
|
||||
|
||||
|
||||
# Only load in this module is the OPENSTACK configurations are in place
|
||||
|
|
|
@ -75,7 +75,7 @@ from salt.exceptions import (
|
|||
import salt.utils.cloud
|
||||
|
||||
from salt.cloud.libcloudfuncs import get_size, get_image, script, show_instance
|
||||
from salt.utils import namespaced_function
|
||||
from salt.utils.functools import namespaced_function
|
||||
|
||||
get_size = namespaced_function(get_size, globals())
|
||||
get_image = namespaced_function(get_image, globals())
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue