Skip to content

Commit

Permalink
Merge pull request #54622 from garethgreenaway/2019_2_1_port_49378
Browse files Browse the repository at this point in the history
[master] Porting #49378 to master
  • Loading branch information
dwoz committed Dec 6, 2019
2 parents b8d6470 + 7b5da87 commit a01b7f5
Show file tree
Hide file tree
Showing 3 changed files with 131 additions and 0 deletions.
29 changes: 29 additions & 0 deletions doc/ref/configuration/minion.rst
Expand Up @@ -652,6 +652,35 @@ FQDN (for instance, Solaris).
append_domain: foo.org
.. conf_minion:: minion_id_remove_domain

``minion_id_remove_domain``
---------------------------

.. versionadded:: Neon

Default: ``False``

Remove a domain when the minion id is generated as a fully qualified domain
name (either by the user provided ``id_function``, or by Salt). This is useful
when the minions shall be named like hostnames. Can be a single domain (to
prevent name clashes), or True, to remove all domains.

Examples:
- minion_id_remove_domain = foo.org
- FQDN = king_bob.foo.org --> minion_id = king_bob
- FQDN = king_bob.bar.org --> minion_id = king_bob.bar.org
- minion_id_remove_domain = True
- FQDN = king_bob.foo.org --> minion_id = king_bob
- FQDN = king_bob.bar.org --> minion_id = king_bob


For more information, please see :issue:`49212` and :pull:`49378`.

.. code-block:: yaml
minion_id_remove_domain: foo.org
.. conf_minion:: minion_id_lowercase

``minion_id_lowercase``
Expand Down
29 changes: 29 additions & 0 deletions salt/config/__init__.py
Expand Up @@ -954,6 +954,9 @@ def _gather_buffer_space():
# Always generate minion id in lowercase.
'minion_id_lowercase': bool,

# Remove either a single domain (foo.org), or all (True) from a generated minion id.
'minion_id_remove_domain': (six.string_types, bool),

# If set, the master will sign all publications before they are sent out
'sign_pub_messages': bool,

Expand Down Expand Up @@ -1440,6 +1443,7 @@ def _gather_buffer_space():
'grains_refresh_every': 0,
'minion_id_caching': True,
'minion_id_lowercase': False,
'minion_id_remove_domain': False,
'keysize': 2048,
'transport': 'zeromq',
'auth_timeout': 5,
Expand Down Expand Up @@ -3565,6 +3569,26 @@ def call_id_function(opts):
sys.exit(salt.defaults.exitcodes.EX_GENERIC)


def remove_domain_from_fqdn(opts, newid):
'''
Depending on the values of `minion_id_remove_domain`,
remove all domains or a single domain from a FQDN, effectivly generating a hostname.
'''
opt_domain = opts.get('minion_id_remove_domain')
if opt_domain is True:
if '.' in newid:
# Remove any domain
newid, xdomain = newid.split('.', 1)
log.debug('Removed any domain (%s) from minion id.', xdomain)
else:
# Must be string type
if newid.upper().endswith('.' + opt_domain.upper()):
# Remove single domain
newid = newid[:-len('.' + opt_domain)]
log.debug('Removed single domain %s from minion id.', opt_domain)
return newid


def get_id(opts, cache_minion_id=False):
'''
Guess the id of the minion.
Expand Down Expand Up @@ -3616,6 +3640,11 @@ def get_id(opts, cache_minion_id=False):
if opts.get('minion_id_lowercase'):
newid = newid.lower()
log.debug('Changed minion id %s to lowercase.', newid)

# Optionally remove one or many domains in a generated minion id
if opts.get('minion_id_remove_domain'):
newid = remove_domain_from_fqdn(opts, newid)

if '__role' in opts and opts.get('__role') == 'minion':
if opts.get('id_function'):
log.debug(
Expand Down
73 changes: 73 additions & 0 deletions tests/unit/test_config.py
Expand Up @@ -707,6 +707,79 @@ def test_minion_id_lowercase(self, tempdir):
self.assertEqual(config['minion_id_lowercase'], True) # Check the configuration
self.assertEqual(config['id'], 'king_bob')

@with_tempdir()
def test_minion_id_remove_domain_string_positive(self, tempdir):
'''
This tests that the values of `minion_id_remove_domain` is suppressed from a generated minion id,
effectivly generating a hostname minion_id.
'''
minion_config = os.path.join(tempdir, 'minion')
with salt.utils.files.fopen(minion_config, 'w') as fp_:
fp_.write(textwrap.dedent('''\
id_function:
test.echo:
text: king_bob.foo.org
minion_id_remove_domain: foo.org
minion_id_caching: False
'''))

# Let's load the configuration
config = sconfig.minion_config(minion_config)
self.assertEqual(config['minion_id_remove_domain'], 'foo.org')
self.assertEqual(config['id'], 'king_bob')

@with_tempdir()
def test_minion_id_remove_domain_string_negative(self, tempdir):
'''
See above
'''
minion_config = os.path.join(tempdir, 'minion')
with salt.utils.files.fopen(minion_config, 'w') as fp_:
fp_.write(textwrap.dedent('''\
id_function:
test.echo:
text: king_bob.foo.org
minion_id_remove_domain: bar.org
minion_id_caching: False
'''))

config = sconfig.minion_config(minion_config)
self.assertEqual(config['id'], 'king_bob.foo.org')

@with_tempdir()
def test_minion_id_remove_domain_bool_true(self, tempdir):
'''
See above
'''
minion_config = os.path.join(tempdir, 'minion')
with salt.utils.files.fopen(minion_config, 'w') as fp_:
fp_.write(textwrap.dedent('''\
id_function:
test.echo:
text: king_bob.foo.org
minion_id_remove_domain: True
minion_id_caching: False
'''))
config = sconfig.minion_config(minion_config)
self.assertEqual(config['id'], 'king_bob')

@with_tempdir()
def test_minion_id_remove_domain_bool_false(self, tempdir):
'''
See above
'''
minion_config = os.path.join(tempdir, 'minion')
with salt.utils.files.fopen(minion_config, 'w') as fp_:
fp_.write(textwrap.dedent('''\
id_function:
test.echo:
text: king_bob.foo.org
minion_id_remove_domain: False
minion_id_caching: False
'''))
config = sconfig.minion_config(minion_config)
self.assertEqual(config['id'], 'king_bob.foo.org')

@with_tempdir()
def test_backend_rename(self, tempdir):
'''
Expand Down

0 comments on commit a01b7f5

Please sign in to comment.