Merge "Configure /etc/default/useradd through 'defaults'"
diff --git a/.kitchen.yml b/.kitchen.yml
index 9901242..eeaf317 100644
--- a/.kitchen.yml
+++ b/.kitchen.yml
@@ -33,16 +33,10 @@
sudo: true
docker_images:
- - &xenial-20163 <%=ENV['IMAGE_XENIAL_20163'] || 'docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2016.3/salt:2018_11_19'%>
- &xenial-20177 <%=ENV['IMAGE_XENIAL_20177'] || 'docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-2017.7/salt:2018_11_19'%>
- &xenial-stable <%=ENV['IMAGE_XENIAL_STABLE'] || 'docker-dev-local.docker.mirantis.net/epcim/salt/saltstack-ubuntu-xenial-salt-stable/salt:2018_11_19'%>
platforms:
- - name: xenial-2016.3
- driver_config:
- image: *xenial-20163
- platform: ubuntu
-
- name: xenial-2017.7
driver_config:
image: *xenial-20177
diff --git a/README.rst b/README.rst
index 9c66374..2993b55 100644
--- a/README.rst
+++ b/README.rst
@@ -561,6 +561,19 @@
foo: 1
bar: 'bar'
+Ensure presence of file to be decoded through file.decode module (see:
+https://docs.saltstack.com/en/latest/ref/states/all/salt.states.file.html#salt.states.file.decode):
+
+.. code-block:: yaml
+
+ linux:
+ system:
+ file:
+ /tmp/test4.txt:
+ decode: True
+ encoded_data: |
+ dGVzdDQK
+
Kernel
~~~~~~
diff --git a/_states/aptkey.py b/_states/aptkey.py
new file mode 100644
index 0000000..8d12829
--- /dev/null
+++ b/_states/aptkey.py
@@ -0,0 +1,121 @@
+# -*- coding: utf-8 -*-
+# _state/aptkey.py
+"""
+Manage apt keys
+"""
+from __future__ import absolute_import, print_function, unicode_literals
+
+from base64 import b64encode, b64decode
+from binascii import Error as binasciiError
+
+def __virtual__():
+ """Only load if 'pkg' (aptpkg) module has necessary functions"""
+
+ if not 'pkg.add_repo_key' in __salt__ or not 'pkg.get_repo_keys' in __salt__:
+ return False, "'pkg.add_repo_key' and 'pkg.get_repo_keys' functions are required"
+ return True
+
+def _get_fingerprints(input_text):
+ """Get fingerprint(s) for given text
+
+ :param str input_text: text to get fingerprint(s) from it
+
+ :return:
+ A list of found fingerprint(s)
+ :rtype list:
+
+ """
+ fingerprints = []
+ cmd = 'apt-key adv --with-fingerprint --with-colons --dry-run -'
+ out = __salt__['cmd.run_stdout'](cmd, stdin=input_text, python_shell=False)
+ for line in out.split('\n'):
+ line = line.split(':')
+ if line[0] == 'fpr':
+ fingerprints.append(line[-2])
+ return fingerprints
+
+
+def added(name, key_text=None, key_url=None):
+ """Ensure that given key added to APT's key storage
+
+ :param str name:
+ Just an ID, it does not used at all.
+ :param str key_text:
+ Key to add as a plain text or base64-encoded.
+ :param str key_url:
+ URL from which key should be fetched. Supported URLs: salt://, http://,
+ https:// and file://.
+
+ Examples:
+
+ .. code-block:: yaml
+
+ # Base64 encoded key
+ {% set repo_key = salt['hashutil.base64_b64encode'](repo.key) %}
+ linux_repo_ubuntu_key:
+ aptkey.added:
+ - key_text: {{ repo_key }}
+
+ .. code-block:: yaml
+
+ # Plaintext key
+ linux_repo_ubuntu_key:
+ aptkey.added:
+ - key_text: '{{ repo.key | replace("\n", "\\n") }}'
+
+ .. code-block:: yaml
+
+ linux_repo_ubuntu_key:
+ aptkey.added:
+ - key_url: 'https://example.com/key.asc'
+ """
+ ret = {'name': name,
+ 'result': None if __opts__['test'] else True,
+ 'changes': {},
+ 'comment': ''}
+
+ if not key_text and not key_url:
+ ret['result'] = False,
+ ret['comment'] = 'No key to add provided'
+ return ret
+ if key_text and key_url:
+ ret['result'] = False
+ ret['comment'] = 'Only one of key_text or key_url is permitted'
+ return ret
+
+ # If key_url provided fetch it before proceeding
+ if key_url:
+ # This only supports salt://, http://, https:// and file:// URLs
+ key_text = __salt__['cp.get_url'](key_url, dest=None)
+
+ # Try to apply base64 decoding to key_text, just in case...
+ try:
+ # Decode key_text if it is base64 encoded string
+ decoded_key_text = b64decode(key_text)
+ # the simplest available check that given string was base64 encoded
+ if b64encode(decoded_key_text) == key_text:
+ key_text = decoded_key_text
+ except TypeError, binasciiError: # the first is for py2, the second for py3
+ pass
+
+ # Get apt's keys and their fingerprints
+ apt_keys = __salt__['pkg.get_repo_keys']()
+ apt_fingerprints = [key.get('fingerprint') for _, key in apt_keys.items()]
+
+ key_fingerprints = _get_fingerprints(key_text)
+ # If any of given fingerprints does not present in apt keys
+ # then add all of them
+ if not set(key_fingerprints).issubset(set(apt_fingerprints)):
+ if __opts__['test']:
+ ret['result'] = None
+ ret['changes'] = {'key': key_text}
+ return ret
+
+ success = __salt__['pkg.add_repo_key'](text=key_text)
+ if success:
+ ret['result'] = True
+ ret['changes'] = {'key': key_text}
+ else:
+ ret['result'] = False
+ ret['comment'] = 'Key was not added because of errors'
+ return ret
diff --git a/linux/system/auth.sls b/linux/system/auth.sls
index 690ec04..5cb3798 100644
--- a/linux/system/auth.sls
+++ b/linux/system/auth.sls
@@ -170,6 +170,7 @@
- pkg: linux_auth_ldap_packages
- watch_in:
- service: linux_auth_nslcd_service
+ - service: linux_auth_nscd_service
linux_auth_ldap_packages:
pkg.installed:
@@ -185,12 +186,18 @@
- pkg: linux_auth_ldap_packages
- watch_in:
- service: linux_auth_nslcd_service
+ - service: linux_auth_nscd_service
linux_auth_nslcd_service:
service.running:
- enable: true
- name: nslcd
+linux_auth_nscd_service:
+ service.running:
+ - enable: true
+ - name: nscd
+
{%- endif %}
{%- endif %}
{%- endif %}
diff --git a/linux/system/file.sls b/linux/system/file.sls
index e8a6d52..1ae9906 100644
--- a/linux/system/file.sls
+++ b/linux/system/file.sls
@@ -3,16 +3,44 @@
{%- for file_name, file in system.file.items() %}
+ {%- if file.decode is defined %}
+ {%- if file.name is defined %}
+ {%- set dirname = salt['file.dirname'](file.name) %}
+ {%- else %}
+ {%- set dirname = salt['file.dirname'](file_name) %}
+ {%- endif %}
+linux_directory_{{ dirname }}:
+ file.directory:
+ - name: {{ dirname }}
+ - makedirs: {{ file.get('makedirs', 'True') }}
+ - user: {{ file.get('user', 'root') }}
+ - group: {{ file.get('group', 'root') }}
+
linux_file_{{ file_name }}:
-{%- if file.serialize is defined %}
+ file.decode:
+ {%- if file.name is defined %}
+ - name: {{ file.name }}
+ {%- else %}
+ - name: {{ file_name }}
+ {%- endif %}
+ - encoding_type: base64
+ {%- if file.contents_pillar is defined %}
+ - contents_pillar: {{ file.contents_pillar }}
+ {%- elif file.encoded_data is defined %}
+ - encoded_data: |
+ {{ file.encoded_data | indent(8) }}
+ {%- endif %}
+ {%- else %}
+linux_file_{{ file_name }}:
+ {%- if file.serialize is defined %}
file.serialize:
- formatter: {{ file.serialize }}
- {%- if file.contents is defined %}
+ {%- if file.contents is defined %}
- dataset: {{ file.contents|yaml }}
- {%- elif file.contents_pillar is defined %}
+ {%- elif file.contents_pillar is defined %}
- dataset_pillar: {{ file.contents_pillar }}
- {%- endif %}
-{%- else %}
+ {%- endif %}
+ {%- else %}
file.managed:
{%- if file.source is defined %}
- source: {{ file.source }}
@@ -31,8 +59,7 @@
{%- elif file.contents_grains is defined %}
- contents_grains: {{ file.contents_grains }}
{%- endif %}
-
-{%- endif %}
+ {%- endif %}
{%- if file.name is defined %}
- name: {{ file.name }}
{%- else %}
@@ -50,6 +77,7 @@
{%- if file.encoding is defined %}
- encoding: {{ file.encoding }}
{%- endif %}
+{%- endif %}
{%- endfor %}
diff --git a/linux/system/repo.sls b/linux/system/repo.sls
index 73bb33d..3322f07 100644
--- a/linux/system/repo.sls
+++ b/linux/system/repo.sls
@@ -80,11 +80,11 @@
- name: /etc/apt/preferences.d/{{ name }}
{%- endif %}
- {%- if repo.get('key') %}
+ {%- if repo.get('key') and grains['saltversioninfo'] < [2018, 3] %}
linux_repo_{{ name }}_key:
{% set repo_key = salt['hashutil.base64_b64encode'](repo.key) %}
- cmd.run:
- - name: "echo '{{ repo_key }}' | base64 -d | apt-key add -"
+ aptkey.added:
+ - key_text: {{ repo_key }}
- require_in:
{%- if repo.get('default', False) %}
- file: default_repo_list
@@ -105,8 +105,8 @@
#}
{%- elif repo.key_url|default(False) and grains['saltversioninfo'] < [2017, 7] and not repo.key_url.startswith('salt://') %}
linux_repo_{{ name }}_key:
- cmd.run:
- - name: "curl -sL {{ repo.key_url }} | apt-key add -"
+ aptkey.added:
+ - key_url: {{ repo.key_url }}
- require_in:
{%- if repo.get('default', False) %}
- file: default_repo_list
@@ -144,6 +144,9 @@
{%- if repo.key_url is defined and (grains['saltversioninfo'] >= [2017, 7] or repo.key_url.startswith('salt://')) %}
- key_url: {{ repo.key_url }}
{%- endif %}
+ {%- if repo.key is defined and grains['saltversioninfo'] >= [2018, 3] %}
+ - key_text: '{{ repo.key | replace("\n", "\\n") }}'
+ {%- endif %}
- consolidate: {{ repo.get('consolidate', False) }}
- require:
- file: /etc/apt/apt.conf.d/99proxies-salt-{{ name }}
diff --git a/tests/pillar/system.sls b/tests/pillar/system.sls
index 73448aa..d5a953e 100644
--- a/tests/pillar/system.sls
+++ b/tests/pillar/system.sls
@@ -34,6 +34,10 @@
name: /tmp/test3.txt
source: salt://linux/files/test/file_template.jinja
template: jinja
+ test4:
+ decode: True
+ name: /tmp/test4.txt
+ encoded_data: dGVzdDQK
apt:
preferences:
enabled: true