Merge "Linux OVS-dpdk and multiqueue support"
diff --git a/.kitchen.yml b/.kitchen.yml
new file mode 100644
index 0000000..2c11074
--- /dev/null
+++ b/.kitchen.yml
@@ -0,0 +1,66 @@
+---
+driver:
+ name: docker
+ hostname: linux.ci.local
+ use_sudo: sudo
+
+provisioner:
+ name: salt_solo
+ salt_install: bootstrap
+ salt_bootstrap_url: https://bootstrap.saltstack.com
+ salt_version: latest
+ require_chef: false
+ log_level: error
+ formula: linux
+ grains:
+ noservices: true
+ state_top:
+ base:
+ "*":
+ - linux
+ pillars:
+ top.sls:
+ base:
+ "*":
+ - linux
+
+verifier:
+ name: inspec
+ sudo: true
+
+platforms:
+ - name: <%=ENV['PLATFORM'] || 'ubuntu-xenial'%>
+ driver_config:
+ image: <%=ENV['PLATFORM'] || 'trevorj/salty-whales:xenial'%>
+ platform: ubuntu
+
+
+suites:
+
+ - name: network
+ provisioner:
+ pillars-from-files:
+ linux.sls: tests/pillar/network.sls
+
+ #- name: storage
+ #provisioner:
+ #pillars-from-files:
+ #linux.sls: tests/pillar/storage.sls
+ #init_environment: |
+ #sudo mkdir -p /tmp/node
+ #sudo dd if=/dev/zero of=/tmp/loop_dev0 bs=1024 count=$((30*1024));
+ #sudo dd if=/dev/zero of=/tmp/loop_dev1 bs=1024 count=$((30*1024));
+ #sudo dd if=/dev/zero of=/tmp/loop_dev2 bs=1024 count=$((30*1024));
+ #sudo dd if=/dev/zero of=/tmp/loop_dev3 bs=1024 count=$((30*1024));
+ #sudo dd if=/dev/zero of=/tmp/loop_dev4 bs=1024 count=$((30*1024));
+ #sudo mkfs.ext4 /tmp/loop_dev1
+ #sudo mkswap /tmp/loop_dev2
+ #sudo chown root /tmp/loop_dev*;
+ #sudo chmod 0600 /tmp/loop_dev*;
+
+ - name: system
+ provisioner:
+ pillars-from-files:
+ linux.sls: tests/pillar/system.sls
+
+# vim: ft=yaml sw=2 ts=2 sts=2 tw=125
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..2a33688
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,30 @@
+sudo: required
+services:
+ - docker
+
+install:
+ - pip install PyYAML
+ - pip install virtualenv
+ - |
+ test -e Gemfile || cat <<EOF > Gemfile
+ source 'https://rubygems.org'
+ gem 'rake'
+ gem 'test-kitchen'
+ gem 'kitchen-docker'
+ gem 'kitchen-inspec'
+ gem 'inspec'
+ gem 'kitchen-salt', :git => 'https://github.com/epcim/kitchen-salt.git', :branch => 'dependencis-pkg-repo2'
+ #Waiting for PR#78
+ #gem 'kitchen-salt', '>=0.2.25'
+ - bundle install
+
+env:
+ - PLATFORM=trevorj/salty-whales:trusty
+ - PLATFORM=trevorj/salty-whales:xenial
+
+before_script:
+ - make test | tail
+
+script:
+ - test ! -e .kitchen.yml || bundle exec kitchen converge || true
+ - test ! -e .kitchen.yml || bundle exec kitchen verify -t tests/integration
diff --git a/README.rst b/README.rst
index 39893c1..c1b8cc7 100644
--- a/README.rst
+++ b/README.rst
@@ -1,4 +1,3 @@
-
=====
Linux
=====
@@ -31,7 +30,7 @@
timezone: 'Europe/Prague'
utc: true
-Linux with system users, sowe with password set
+Linux with system users, some with password set
.. code-block:: yaml
@@ -54,6 +53,115 @@
home: '/home/jsmith'
password: userpassword
+Configure sudo for users and groups under ``/etc/sudoers.d/``.
+This ways ``linux.system.sudo`` pillar map to actual sudo attributes:
+
+.. code-block:: jinja
+ # simplified template:
+ Cmds_Alias {{ alias }}={{ commands }}
+ {{ user }} {{ hosts }}=({{ runas }}) NOPASSWD: {{ commands }}
+ %{{ group }} {{ hosts }}=({{ runas }}) NOPASSWD: {{ commands }}
+
+ # when rendered:
+ saltuser1 ALL=(ALL) NOPASSWD: ALL
+
+
+.. code-block:: yaml
+ linux:
+ system:
+ sudo:
+ enabled: true
+ alias:
+ host:
+ LOCAL:
+ - localhost
+ PRODUCTION:
+ - db1
+ - db2
+ runas:
+ DBA:
+ - postgres
+ - mysql
+ SALT:
+ - root
+ command:
+ # Note: This is not 100% safe when ALL keyword is used, user still may modify configs and hide his actions.
+ # Best practice is to specify full list of commands user is allowed to run.
+ SUPPORT_RESTRICTED:
+ - /bin/vi /etc/sudoers*
+ - /bin/vim /etc/sudoers*
+ - /bin/nano /etc/sudoers*
+ - /bin/emacs /etc/sudoers*
+ - /bin/su - root
+ - /bin/su -
+ - /bin/su
+ - /usr/sbin/visudo
+ SUPPORT_SHELLS:
+ - /bin/sh
+ - /bin/ksh
+ - /bin/bash
+ - /bin/rbash
+ - /bin/dash
+ - /bin/zsh
+ - /bin/csh
+ - /bin/fish
+ - /bin/tcsh
+ - /usr/bin/login
+ - /usr/bin/su
+ - /usr/su
+ ALL_SALT_SAFE:
+ - /usr/bin/salt state*
+ - /usr/bin/salt service*
+ - /usr/bin/salt pillar*
+ - /usr/bin/salt grains*
+ - /usr/bin/salt saltutil*
+ - /usr/bin/salt-call state*
+ - /usr/bin/salt-call service*
+ - /usr/bin/salt-call pillar*
+ - /usr/bin/salt-call grains*
+ - /usr/bin/salt-call saltutil*
+ SALT_TRUSTED:
+ - /usr/bin/salt*
+ users:
+ # saltuser1 with default values: saltuser1 ALL=(ALL) NOPASSWD: ALL
+ saltuser1: {}
+ saltuser2:
+ hosts:
+ - LOCAL
+ # User Alias DBA
+ DBA:
+ hosts:
+ - ALL
+ commands:
+ - ALL_SALT_SAFE
+ groups:
+ db-ops:
+ hosts:
+ - ALL
+ - '!PRODUCTION'
+ runas:
+ - DBA
+ commands:
+ - /bin/cat *
+ - /bin/less *
+ - /bin/ls *
+ salt-ops:
+ hosts:
+ - 'ALL'
+ runas:
+ - SALT
+ commands:
+ - SUPPORT_SHELLS
+ salt-ops-2nd:
+ name: salt-ops
+ nopasswd: false
+ runas:
+ - DBA
+ commands:
+ - ALL
+ - '!SUPPORT_SHELLS'
+ - '!SUPPORT_RESTRICTED'
+
Linux with package, latest version
.. code-block:: yaml
diff --git a/linux/files/sudoer b/linux/files/sudoer
index 3b682af..549d5f9 100644
--- a/linux/files/sudoer
+++ b/linux/files/sudoer
@@ -1,5 +1,6 @@
-# managed by salt
-
+# sudoer file managed by salt-minion
+# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
+#
# user {{ user_name }} is system administrator.
# It has passwordless sudo functionality.
{{ user_name }} ALL=(ALL) NOPASSWD:ALL
diff --git a/linux/files/sudoer-aliases b/linux/files/sudoer-aliases
new file mode 100644
index 0000000..9e44886
--- /dev/null
+++ b/linux/files/sudoer-aliases
@@ -0,0 +1,19 @@
+# sudoer aliases, file managed by salt-minion
+# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
+
+{%- for alias,commands in aliases.get('command',{}).iteritems() %}
+Cmnd_Alias {{ alias }}={{ commands|join(', ') }}
+{%- endfor %}
+
+{%- for alias,users in aliases.get('user',{}).iteritems() %}
+User_Alias {{ alias }}={{ users|join(', ') }}
+{%- endfor %}
+
+{%- for alias,users in aliases.get('runas',{}).iteritems() %}
+Runas_Alias {{ alias }}={{ users|join(', ') }}
+{%- endfor %}
+
+{%- for alias,hosts in aliases.get('host',{}).iteritems() %}
+Host_Alias {{ alias }}={{ hosts|join(', ') }}
+{%- endfor %}
+
diff --git a/linux/files/sudoer-groups b/linux/files/sudoer-groups
new file mode 100644
index 0000000..b0c1fdf
--- /dev/null
+++ b/linux/files/sudoer-groups
@@ -0,0 +1,7 @@
+# sudoer groups, file managed by salt-minion
+# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
+
+{%- for group,spec in groups.iteritems() %}
+%{{ spec.name|default(group) }} {{ spec.get('hosts', ['ALL'])|join(',') }}=({{ spec.get('runas', ['ALL'])|join(', ') }}) {% if spec.get('nopasswd', True) %}NOPASSWD: {% endif %}{{ spec.get('commands', ['ALL'])|join(', ') }}
+{%- endfor %}
+
diff --git a/linux/files/sudoer-users b/linux/files/sudoer-users
new file mode 100644
index 0000000..4e05269
--- /dev/null
+++ b/linux/files/sudoer-users
@@ -0,0 +1,7 @@
+# sudoer users, file managed by salt-minion
+# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
+
+{%- for user,spec in users.iteritems() %}
+{{ spec.name|default(user) }} {{ spec.get('hosts', ['ALL'])|join(',') }}=({{ spec.get('runas', ['ALL'])|join(', ') }}) {% if spec.get('nopasswd', True) %}NOPASSWD: {% endif %}{{ spec.get('commands', ['ALL'])|join(', ') }}
+{%- endfor %}
+
diff --git a/linux/network/interface.sls b/linux/network/interface.sls
index 0b1f0ee..a72f472 100644
--- a/linux/network/interface.sls
+++ b/linux/network/interface.sls
@@ -202,7 +202,7 @@
{%- endif %}
- nozeroconf: True
- nisdomain: {{ system.domain }}
- - require_reboot: False
+ - require_reboot: True
{%- endif %}
diff --git a/linux/system/group.sls b/linux/system/group.sls
index 4963829..2c1c769 100644
--- a/linux/system/group.sls
+++ b/linux/system/group.sls
@@ -26,3 +26,4 @@
{%- endfor %}
{%- endif %}
+
diff --git a/linux/system/init.sls b/linux/system/init.sls
index 1ce8100..9d4d4f0 100644
--- a/linux/system/init.sls
+++ b/linux/system/init.sls
@@ -75,3 +75,6 @@
{%- if system.config is defined %}
- linux.system.config
{%- endif %}
+{%- if system.sudo is defined %}
+- linux.system.sudo
+{%- endif %}
diff --git a/linux/system/repo.sls b/linux/system/repo.sls
index 04e7070..555abd1 100644
--- a/linux/system/repo.sls
+++ b/linux/system/repo.sls
@@ -58,6 +58,8 @@
{%- if repo.key_url is defined %}
- key_url: {{ repo.key_url }}
{%- endif %}
+ - require:
+ - pkg: linux_packages
{%- endif %}
@@ -80,6 +82,8 @@
{%- if repo.gpgkey is defined %}
- gpgkey: {{ repo.gpgkey }}
{%- endif %}
+ - require:
+ - pkg: linux_packages
{%- endif %}
@@ -99,6 +103,8 @@
- mode: 0644
- defaults:
default_repos: {{ default_repos }}
+ - require:
+ - pkg: linux_packages
{%- endif %}
diff --git a/linux/system/sudo.sls b/linux/system/sudo.sls
new file mode 100644
index 0000000..5cee4b3
--- /dev/null
+++ b/linux/system/sudo.sls
@@ -0,0 +1,73 @@
+{%- from "linux/map.jinja" import system with context %}
+{%- if system.enabled %}
+
+{%- if system.get('sudo', {}).get('enabled', False) %}
+
+{%- if system.get('sudo', {}).get('aliases', False) is mapping %}
+/etc/sudoers.d/90-salt-sudo-aliases:
+ file.managed:
+ - source: salt://linux/files/sudoer-aliases
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 440
+ - defaults:
+ aliases: {{ system.sudo.aliases|yaml }}
+ - check_cmd: /usr/sbin/visudo -c -f
+{%- else %}
+/etc/sudoers.d/90-salt-sudo-aliases:
+ file.absent:
+ - name: /etc/sudoers.d/90-salt-sudo-aliases
+{%- endif %}
+
+
+{%- if system.get('sudo', {}).get('users', False) is mapping %}
+/etc/sudoers.d/91-salt-sudo-users:
+ file.managed:
+ - source: salt://linux/files/sudoer-users
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 440
+ - defaults:
+ users: {{ system.sudo.users|yaml }}
+ - check_cmd: /usr/sbin/visudo -c -f
+{%- else %}
+/etc/sudoers.d/91-salt-sudo-users:
+ file.absent:
+ - name: /etc/sudoers.d/91-salt-sudo-users
+{%- endif %}
+
+{%- if system.get('sudo', {}).get('groups', False) is mapping %}
+/etc/sudoers.d/91-salt-sudo-groups:
+ file.managed:
+ - source: salt://linux/files/sudoer-groups
+ - template: jinja
+ - user: root
+ - group: root
+ - mode: 440
+ - defaults:
+ groups: {{ system.sudo.groups|yaml }}
+ - check_cmd: /usr/sbin/visudo -c -f
+{%- else %}
+/etc/sudoers.d/91-salt-sudo-groups:
+ file.absent:
+ - name: /etc/sudoers.d/91-salt-sudo-groups
+{%- endif %}
+
+{%- else %}
+
+/etc/sudoers.d/90-salt-sudo-aliases:
+ file.absent:
+ - name: /etc/sudoers.d/90-salt-sudo-aliases
+
+/etc/sudoers.d/91-salt-sudo-users:
+ file.absent:
+ - name: /etc/sudoers.d/91-salt-sudo-users
+
+/etc/sudoers.d/91-salt-sudo-groups:
+ file.absent:
+ - name: /etc/sudoers.d/91-salt-sudo-groups
+
+{%- endif %}
+{%- endif %}
diff --git a/linux/system/user.sls b/linux/system/user.sls
index 4232e65..997f6fa 100644
--- a/linux/system/user.sls
+++ b/linux/system/user.sls
@@ -48,6 +48,7 @@
user_name: {{ name }}
- require:
- user: system_user_{{ name }}
+ - check_cmd: /usr/sbin/visudo -c -f
{%- endif %}
diff --git a/tests/integration/system/sudoer_spec.rb b/tests/integration/system/sudoer_spec.rb
new file mode 100644
index 0000000..21163cf
--- /dev/null
+++ b/tests/integration/system/sudoer_spec.rb
@@ -0,0 +1,8 @@
+describe command('grep "" /etc/sudoers.d/*') do
+ its('stdout') { should_not match /sudogroup0/ }
+ its('stdout') { should match /salt-ops ALL=\(DBA\) NOPASSWD/ }
+ its('stdout') { should match /sudogroup2.*localhost=/ }
+ its('stdout') { should match /db-ops.*less/ }
+ its('stdout') { should_not match /sudogroup0/ }
+ its('stdout') { should_not match /sudogroup1 .* !SUDO_RESTRICTED_SU/ }
+end
diff --git a/tests/pillar/network.sls b/tests/pillar/network.sls
index a8dfee6..bf8b176 100644
--- a/tests/pillar/network.sls
+++ b/tests/pillar/network.sls
@@ -1,25 +1,26 @@
linux:
system:
enabled: true
- domain: local
+ domain: ci.local
+ name: linux
network:
enabled: true
- hostname: test01
- fqdn: test01.local
+ hostname: linux
+ fqdn: linux.ci.local
network_manager: false
- interface:
- eth0:
- enabled: true
- type: eth
- address: 192.168.0.102
- netmask: 255.255.255.0
- gateway: 192.168.0.1
- name_servers:
- - 8.8.8.8
- - 8.8.4.4
- mtu: 1500
- vlan69:
- enabled: true
- type: vlan
- use_interfaces:
- - interface: ${linux:interface:eth0}
+ #interface:
+ #eth0:
+ #enabled: true
+ #type: eth
+ #address: 192.168.0.102
+ #netmask: 255.255.255.0
+ #gateway: 192.168.0.1
+ #name_servers:
+ #- 8.8.8.8
+ #- 8.8.4.4
+ #mtu: 1500
+ #vlan69:
+ #enabled: true
+ #type: vlan
+ #use_interfaces:
+ #- interface: ${linux:interface:eth0}
diff --git a/tests/pillar/storage.sls b/tests/pillar/storage.sls
index af9e2fd..af63dbe 100644
--- a/tests/pillar/storage.sls
+++ b/tests/pillar/storage.sls
@@ -5,23 +5,42 @@
file:
enabled: true
engine: file
- device: /swapfile
- size: 512
+ device: /tmp/loop_dev2
+ size: 5
+ mount:
+ # NOTE: simple dummy loop devices, use for test purposes only
+ dev0:
+ enabled: false
+ device: /tmp/loop_dev0
+ path: /tmp/node/dev0
+ file_system: xfs
+ opts: noatime,nobarrier,logbufs=8,nobootwait,nobarrier
+ user: root
+ group: root
+ mode: 755
+ dev1:
+ enabled: true
+ device: /tmp/loop_dev1
+ path: /mnt
+ file_system: ext4
+ #opts: noatime,nobarrier,logbufs=8,nobootwait,nobarrier
+ user: root
+ group: root
lvm:
vg0:
name: vg0-dummy
enabled: true
devices:
- - /dev/vdb
+ - /tmp/loop_dev3
volume:
lv01:
- size: 512M
+ size: 5M
mount:
- path: /srv
+ path: /mnt
disk1:
enabled: true
- device: /dev/dummy
- path: /srv/dummy
+ device: /dev/loop_dev4
+ path: /tmp/dummy
file_system: xfs
options: "noatime,nobarrier,logbufs=8"
user: nobody
diff --git a/tests/pillar/system.sls b/tests/pillar/system.sls
index 30968e2..d92dc8e 100644
--- a/tests/pillar/system.sls
+++ b/tests/pillar/system.sls
@@ -2,32 +2,18 @@
system:
enabled: true
cluster: default
- name: test01
- timezone: Europe/Prague
+ name: linux
domain: local
environment: prd
+ hostname: system.pillar.local
apparmor:
enabled: false
haveged:
enabled: true
- console:
- tty0:
- autologin: root
- ttyS0:
- autologin: root
- rate: 115200
- term: xterm
prompt:
- default: "test01.local$"
+ default: "linux.ci.local$"
kernel:
- sriov: True
isolcpu: 1,2,3,4
- hugepages:
- large:
- default: true
- size: 1G
- count: 210
- mount_point: /mnt/hugepages_1GB
motd:
- warning: |
#!/bin/sh
@@ -55,12 +41,43 @@
uid: 9999
full_name: Test User
home: /home/test
+ groups:
+ - root
+ salt_user1:
+ enabled: true
+ name: saltuser1
+ sudo: false
+ uid: 9991
+ full_name: Salt User1
+ home: /home/saltuser1
+ salt_user2:
+ enabled: true
+ name: saltuser2
+ sudo: false
+ uid: 9992
+ full_name: Salt Sudo User2
+ home: /home/saltuser2
group:
test:
enabled: true
name: test
gid: 9999
system: true
+ db-ops:
+ enabled: true
+ name: testgroup
+ salt-ops:
+ enabled: true
+ name: sudogroup0
+ sudogroup1:
+ enabled: true
+ name: sudogroup1
+ sudogroup2:
+ enabled: true
+ name: sudogroup2
+ sudogroup3:
+ enabled: false
+ name: sudogroup3
job:
test:
enabled: true
@@ -75,11 +92,6 @@
opencontrail:
source: "deb http://ppa.launchpad.net/tcpcloud/contrail-2.20/ubuntu trusty main"
architectures: amd64
- policyrcd:
- - package: cassandra
- action: exit 101
- - package: '*'
- action: switch
locale:
en_US.UTF-8:
enabled: true
@@ -88,3 +100,103 @@
enabled: true
autoupdates:
enabled: true
+ sudo:
+ enabled: true
+ alias:
+ runas:
+ DBA:
+ - postgres
+ - mysql
+ SALT:
+ - root
+ host:
+ LOCAL:
+ - localhost
+ PRODUCTION:
+ - db1
+ - db2
+ command:
+ SUDO_RESTRICTED_SU:
+ - /bin/vi /etc/sudoers
+ - /bin/su - root
+ - /bin/su -
+ - /bin/su
+ - /usr/sbin/visudo
+ SUDO_SHELLS:
+ - /bin/sh
+ - /bin/ksh
+ - /bin/bash
+ - /bin/rbash
+ - /bin/dash
+ - /bin/zsh
+ - /bin/csh
+ - /bin/fish
+ - /bin/tcsh
+ - /usr/bin/login
+ - /usr/bin/su
+ - /usr/su
+ SUDO_SALT_SAFE:
+ - /usr/bin/salt state*
+ - /usr/bin/salt service*
+ - /usr/bin/salt pillar*
+ - /usr/bin/salt grains*
+ - /usr/bin/salt saltutil*
+ - /usr/bin/salt-call state*
+ - /usr/bin/salt-call service*
+ - /usr/bin/salt-call pillar*
+ - /usr/bin/salt-call grains*
+ - /usr/bin/salt-call saltutil*
+ SUDO_SALT_TRUSTED:
+ - /usr/bin/salt*
+ users:
+ saltuser1: {}
+ saltuser2:
+ hosts:
+ - LOCAL
+ # User Alias:
+ DBA:
+ hosts:
+ - ALL
+ commands:
+ - SUDO_SALT_SAFE
+ groups:
+ db-ops:
+ hosts:
+ - ALL
+ - '!PRODUCTION'
+ runas:
+ - DBA
+ commands:
+ - /bin/cat *
+ - /bin/less *
+ - /bin/ls *
+ - SUDO_SALT_SAFE
+ - '!SUDO_SHELLS'
+ - '!SUDO_RESTRICTED_SU'
+ salt-ops:
+ hosts:
+ - 'ALL'
+ runas:
+ - SALT
+ commands:
+ - SUDO_SALT_TRUSTED
+ salt-ops2:
+ name: salt-ops
+ runas:
+ - DBA
+ commands:
+ - SUDO_SHELLS
+ sudogroup1:
+ commands:
+ - ALL
+ sudogroup2:
+ commands:
+ - ALL
+ hosts:
+ - localhost
+ users:
+ - test
+ nopasswd: false
+ sudogroup3:
+ commands:
+ - ALL
diff --git a/tests/pillar/system_extra.sls b/tests/pillar/system_extra.sls
new file mode 100644
index 0000000..801c628
--- /dev/null
+++ b/tests/pillar/system_extra.sls
@@ -0,0 +1,28 @@
+
+linux:
+ system:
+ enabled: true
+ cluster: default
+ name: linux
+ timezone: Europe/Prague
+ console:
+ tty0:
+ autologin: root
+ ttyS0:
+ autologin: root
+ rate: 115200
+ term: xterm
+ kernel:
+ sriov: True
+ isolcpu: 1,2,3,4
+ hugepages:
+ large:
+ default: true
+ size: 1G
+ count: 210
+ mount_point: /mnt/hugepages_1GB
+ policyrcd:
+ - package: cassandra
+ action: exit 101
+ - package: '*'
+ action: switch