Skip to content

Commit

Permalink
Merge branch 'develop' into state-sls-docs
Browse files Browse the repository at this point in the history
  • Loading branch information
Bryce Larson authored Aug 8, 2019
2 parents 38d146f + 57fd04b commit e444548
Show file tree
Hide file tree
Showing 6 changed files with 539 additions and 44 deletions.
6 changes: 4 additions & 2 deletions doc/topics/development/conventions/formulas.rst
Original file line number Diff line number Diff line change
Expand Up @@ -222,8 +222,10 @@ repository in your own account on GitHub and notify a SaltStack employee when
it is ready. We will add you to the Contributors team on the
`saltstack-formulas`_ organization and help you transfer the repository over.
Ping a SaltStack employee on IRC (``#salt`` on Freenode), join the
``#formulas`` channel on the `salt-slack`_ or send an email to the
`salt-users`_ mailing list.
``#formulas`` channel on the `salt-slack`_ (bridged to ``#saltstack-formulas``
on Freenode) or send an email to the `salt-users`_ mailing list. Note that the
IRC logs are available at https://freenode.logbot.info/salt and
https://freenode.logbot.info/saltstack-formulas respectively.

There are a lot of repositories in that organization! Team members can manage
which repositories they are subscribed to on GitHub's watching page:
Expand Down
9 changes: 9 additions & 0 deletions salt/grains/mdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,9 @@ def _user_mdata(mdata_list=None, mdata_get=None):
return grains

for mdata_grain in __salt__['cmd.run'](mdata_list, ignore_retcode=True).splitlines():
if mdata_grain.startswith("ERROR:"):
log.warning("mdata-list returned an error, skipping mdata grains.")
continue
mdata_value = __salt__['cmd.run']('{0} {1}'.format(mdata_get, mdata_grain), ignore_retcode=True)

if not mdata_grain.startswith('sdc:'):
Expand All @@ -89,6 +92,7 @@ def _sdc_mdata(mdata_list=None, mdata_get=None):
'datacenter_name',
'hostname',
'dns_domain',
'alias',
]
sdc_json_keys = [
'resolvers',
Expand All @@ -107,6 +111,11 @@ def _sdc_mdata(mdata_list=None, mdata_get=None):

for mdata_grain in sdc_text_keys+sdc_json_keys:
mdata_value = __salt__['cmd.run']('{0} sdc:{1}'.format(mdata_get, mdata_grain), ignore_retcode=True)
if mdata_value.startswith("ERROR:"):
log.warning("unable to read sdc:{0} via mdata-get, mdata grain may be incomplete.".format(
mdata_grain,
))
continue

if not mdata_value.startswith('No metadata for '):
if 'mdata' not in grains:
Expand Down
73 changes: 43 additions & 30 deletions salt/grains/smartos.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,14 +107,14 @@ def _smartos_zone_data():
# zoneid
# zonename
# imageversion
grains = {}

grains = {
'zoneid': __salt__['cmd.run']('zoneadm list -p | awk -F: \'{ print $1 }\'', python_shell=True),
'zonename': __salt__['cmd.run']('zonename'),
'imageversion': 'Unknown',
}
zoneinfo = __salt__['cmd.run']('zoneadm list -p').strip().split(":")
grains["zoneid"] = zoneinfo[0]
grains["zonename"] = zoneinfo[1]

imageversion = re.compile('Image:\\s(.+)')
grains["imageversion"] = "Unknown"
if os.path.isfile('/etc/product'):
with salt.utils.files.fopen('/etc/product', 'r') as fp_:
for line in fp_:
Expand All @@ -139,30 +139,38 @@ def _smartos_zone_pkgsrc_data():
'pkgsrcpath': 'Unknown',
}

pkgsrcversion = re.compile('^release:\\s(.+)')
if os.path.isfile('/etc/pkgsrc_version'):
with salt.utils.files.fopen('/etc/pkgsrc_version', 'r') as fp_:
for line in fp_:
line = salt.utils.stringutils.to_unicode(line)
match = pkgsrcversion.match(line)
if match:
grains['pkgsrcversion'] = match.group(1)

# NOTE: we are specifically interested in the SmartOS pkgsrc version and path
# - PKG_PATH MAY be different on non-SmartOS systems, but they will not
# use this grains module.
# - A sysadmin with advanced needs COULD create a 'spin' with a totally
# different URL. But at that point the value would be meaning less in
# the context of the pkgsrcversion grain as it will not followed the
# SmartOS pkgsrc versioning. So 'Unknown' would be appropriate.
pkgsrcpath = re.compile('PKG_PATH=(.+)')
if os.path.isfile('/opt/local/etc/pkg_install.conf'):
with salt.utils.files.fopen('/opt/local/etc/pkg_install.conf', 'r') as fp_:
for line in fp_:
line = salt.utils.stringutils.to_unicode(line)
match = pkgsrcpath.match(line)
if match:
grains['pkgsrcpath'] = match.group(1)
pkgsrcversion = re.compile('^https?://pkgsrc.joyent.com/packages/SmartOS/(.+)/(.+)/All$')
pkg_install_paths = [
'/opt/local/etc/pkg_install.conf',
'/opt/tools/etc/pkg_install.conf',
]
for pkg_install in pkg_install_paths:
if os.path.isfile(pkg_install):
with salt.utils.files.fopen(pkg_install, 'r') as fp_:
for line in fp_:
line = salt.utils.stringutils.to_unicode(line)
match_pkgsrcpath = pkgsrcpath.match(line)
if match_pkgsrcpath:
grains['pkgsrcpath'] = match_pkgsrcpath.group(1)
match_pkgsrcversion = pkgsrcversion.match(match_pkgsrcpath.group(1))
if match_pkgsrcversion:
grains['pkgsrcversion'] = match_pkgsrcversion.group(1)
break

return grains


def _smartos_zone_pkgin_data():
'''
SmartOS zone pkgsrc information
SmartOS zone pkgin information
'''
# Provides:
# pkgin_repositories
Expand All @@ -172,12 +180,17 @@ def _smartos_zone_pkgin_data():
}

pkginrepo = re.compile('^(?:https|http|ftp|file)://.*$')
if os.path.isfile('/opt/local/etc/pkgin/repositories.conf'):
with salt.utils.files.fopen('/opt/local/etc/pkgin/repositories.conf', 'r') as fp_:
for line in fp_:
line = salt.utils.stringutils.to_unicode(line)
if pkginrepo.match(line):
grains['pkgin_repositories'].append(line)
repositories_path = [
'/opt/local/etc/pkgin/repositories.conf',
'/opt/tools/etc/pkgin/repositories.conf',
]
for repositories in repositories_path:
if os.path.isfile(repositories):
with salt.utils.files.fopen(repositories, 'r') as fp_:
for line in fp_:
line = salt.utils.stringutils.to_unicode(line).strip()
if pkginrepo.match(line):
grains['pkgin_repositories'].append(line)

return grains

Expand All @@ -190,10 +203,10 @@ def smartos():

if salt.utils.platform.is_smartos_zone():
grains = salt.utils.dictupdate.update(grains, _smartos_zone_data(), merge_lists=True)
grains = salt.utils.dictupdate.update(grains, _smartos_zone_pkgsrc_data(), merge_lists=True)
grains = salt.utils.dictupdate.update(grains, _smartos_zone_pkgin_data(), merge_lists=True)
elif salt.utils.platform.is_smartos_globalzone():
grains = salt.utils.dictupdate.update(grains, _smartos_computenode_data(), merge_lists=True)
grains = salt.utils.dictupdate.update(grains, _smartos_zone_pkgin_data(), merge_lists=True)
grains = salt.utils.dictupdate.update(grains, _smartos_zone_pkgsrc_data(), merge_lists=True)

return grains

Expand Down
26 changes: 14 additions & 12 deletions salt/utils/platform.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,16 +91,17 @@ def is_smartos_globalzone():
if not is_smartos():
return False
else:
cmd = ['zonename']
try:
zonename = subprocess.Popen(
cmd, shell=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
zonename_proc = subprocess.Popen(
['zonename'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
)
zonename_output = zonename_proc.communicate()[0].strip().decode(__salt_system_encoding__)
zonename_retcode = zonename_proc.poll()
except OSError:
return False
if zonename.returncode:
if zonename_retcode:
return False
if zonename.stdout.read().strip() == 'global':
if zonename_output == 'global':
return True

return False
Expand All @@ -114,16 +115,17 @@ def is_smartos_zone():
if not is_smartos():
return False
else:
cmd = ['zonename']
try:
zonename = subprocess.Popen(
cmd, shell=False,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
zonename_proc = subprocess.Popen(
['zonename'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
)
zonename_output = zonename_proc.communicate()[0].strip().decode(__salt_system_encoding__)
zonename_retcode = zonename_proc.poll()
except OSError:
return False
if zonename.returncode:
if zonename_retcode:
return False
if zonename.stdout.read().strip() == 'global':
if zonename_output == 'global':
return False

return True
Expand Down
189 changes: 189 additions & 0 deletions tests/unit/grains/test_mdata.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
# -*- coding: utf-8 -*-
'''
:codeauthor: :email:`Jorge Schrauwen <sjorge@blackdot.be>`
'''
# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals

# Import Salt Testing Libs
from tests.support.unit import TestCase, skipIf
from tests.support.mock import (
patch,
NO_MOCK,
NO_MOCK_REASON,
Mock,
)

# Import Salt Libs
import salt.grains.mdata as mdata


@skipIf(NO_MOCK, NO_MOCK_REASON)
class MdataGrainsTestCase(TestCase):
'''
Test cases for mdata grains
'''
def setup_loader_modules(self):
return {
mdata: {
'__salt__': {},
},
}

def test_user_mdata_missing_cmd_both(self):
'''
When both or either of the commands is missing there should
be no grain output.
'''
grains_exp_res = {}

which_mock = Mock(side_effect=[
None,
None,
])
with patch('salt.utils.path.which', which_mock):
grains_res = mdata._user_mdata()
self.assertEqual(grains_exp_res, grains_res)

def test_user_mdata_missing_cmd_one(self):
'''
When both or either of the commands is missing there should
be no grain output.
'''
grains_exp_res = {}

which_mock = Mock(side_effect=[
"/usr/sbin/mdata-list",
None,
])
with patch('salt.utils.path.which', which_mock):
grains_res = mdata._user_mdata()
self.assertEqual(grains_exp_res, grains_res)

def test_user_mdata_empty_list(self):
'''
When there are no user grains, there are no mdata-get calls
so there are also no grains.
'''
grains_exp_res = {}

which_mock = Mock(side_effect=[
"/usr/sbin/mdata-list",
"/usr/sbin/mdata-get",
])
cmd_mock = Mock(side_effect=[
"",
])
with patch('salt.utils.path.which', which_mock), \
patch.dict(mdata.__salt__, {'cmd.run': cmd_mock}):
grains_res = mdata._user_mdata()
self.assertEqual(grains_exp_res, grains_res)

def test_user_mdata(self):
'''
We have a list of two grains, so there should be two mdata-get
calls, resulting in 2 grains.
'''
grains_exp_res = {
'mdata': {
'multi_text_data': 'multi\nline\ntext',
'simple_text_data': 'some text data',
},
}

which_mock = Mock(side_effect=[
"/usr/sbin/mdata-list",
"/usr/sbin/mdata-get",
])
cmd_mock = Mock(side_effect=[
"simple_text_data\nmulti_text_data",
"some text data",
"multi\nline\ntext",
])
with patch('salt.utils.path.which', which_mock), \
patch.dict(mdata.__salt__, {'cmd.run': cmd_mock}):
grains_res = mdata._user_mdata()

self.assertEqual(grains_exp_res, grains_res)

def test_sdc_mdata_missing_cmd_both(self):
'''
When both or either of the commands is missing there should
be no grain output.
'''
which_mock = Mock(side_effect=[
None,
None,
])
with patch('salt.utils.path.which', which_mock):
grains = mdata._sdc_mdata()
assert grains == {}

def test_sdc_mdata_missing_cmd_one(self):
'''
When both or either of the commands is missing there should
be no grain output.
'''
grains_exp_res = {}

which_mock = Mock(side_effect=[
"/usr/sbin/mdata-list",
None,
])
with patch('salt.utils.path.which', which_mock):
grains_res = mdata._sdc_mdata()
self.assertEqual(grains_exp_res, grains_res)

def test_sdc_mdata(self):
'''
Simulate all mdata_get calls from a test zone.
'''
grains_exp_res = {
'mdata': {
'sdc': {
'alias': 'test',
'dns_domain': 'example.org',
'hostname': 'test_salt',
'nics': [
{
'gateway': '10.12.3.1',
'gateways': ['10.12.3.1'],
'interface': 'net0',
'ip': '10.12.3.123',
'ips': ['10.12.3.123/24', '2001:ffff:ffff:123::123/64'],
'mac': '00:00:00:00:00:01',
'mtu': 1500,
'netmask': '255.255.255.0',
'nic_tag': 'trunk',
'primary': True,
'vlan_id': 123,
}
],
'resolvers': ['10.12.3.1', '2001:ffff:ffff:123::1'],
'routes': [],
'server_uuid': '00000000-0000-0000-0000-000123456789',
'uuid': 'bae504b1-4594-47de-e2ed-e4f454776689',
},
},
}

which_mock = Mock(side_effect=[
"/usr/sbin/mdata-list",
"/usr/sbin/mdata-get",
])
cmd_mock = Mock(side_effect=[
"bae504b1-4594-47de-e2ed-e4f454776689",
"00000000-0000-0000-0000-000123456789",
"No metadata for 'sdc:datacenter_name'",
"test_salt",
"example.org",
"test",
'["10.12.3.1","2001:ffff:ffff:123::1"]',
'[{"interface":"net0","mac":"00:00:00:00:00:01","vlan_id":123,"nic_tag":"trunk","gateway":"10.12.3.1","gateways":["10.12.3.1"],"netmask":"255.255.255.0","ip":"10.12.3.123","ips":["10.12.3.123/24","2001:ffff:ffff:123::123/64"],"mtu":1500,"primary":true}]',
"[]",
])
with patch('salt.utils.path.which', which_mock), \
patch.dict(mdata.__salt__, {'cmd.run': cmd_mock}):
grains_res = mdata._sdc_mdata()

self.assertEqual(grains_exp_res, grains_res)
Loading

0 comments on commit e444548

Please sign in to comment.