Skip to content

Commit

Permalink
salt/solutions: Revamp configuration file
Browse files Browse the repository at this point in the history
A new field, currently named `active` (may be a poor choice, we'll see
with first user interactions, `activeVersions` could be more explicit),
is introduced to set which version of a Solution should be used for the
cluster-wide components of this Solution (i.e. the Admin UI and CRDs for
now).
Validation of the file format is added, using the usual `kind` and
`apiVersion` fields. Later improvements could use some OpenAPI schema.

Fixes: #1582
  • Loading branch information
gdemonet committed Oct 14, 2019
1 parent 77a167e commit 18a2ac0
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 26 deletions.
53 changes: 46 additions & 7 deletions salt/_modules/metalk8s_solutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
'''
import json
import logging

import yaml

from salt.exceptions import CommandExecutionError

HAS_LIBS = True
SOLUTIONS_CONFIG_MAP = 'metalk8s-solutions'
SOLUTIONS_CONFIG_MAP_NAMESPACE = 'metalk8s-solutions'
SOLUTIONS_CONFIG_FILE = '/etc/metalk8s/solutions.yaml'
try:
import kubernetes.client
from kubernetes.client.rest import ApiException
Expand All @@ -20,6 +18,14 @@

log = logging.getLogger(__name__)

SOLUTIONS_CONFIG_MAP = 'metalk8s-solutions'
SOLUTIONS_CONFIG_MAP_NAMESPACE = 'metalk8s-solutions'

SOLUTIONS_CONFIG_FILE = '/etc/metalk8s/solutions.yaml'
SUPPORTED_CONFIG_VERSIONS = frozenset((
'solutions.metalk8s.scality.com/{}'.format(version)
for version in ['v1alpha1']
))

__virtualname__ = 'metalk8s_solutions'

Expand Down Expand Up @@ -51,16 +57,49 @@ def list_deployed(
}


def list_configured():
"""Get list of Solution archives paths defined in a config file."""
def read_config():
"""Read the SolutionsConfiguration file and return its contents.
Empty containers will be used for `archives` and `active` in the return
value.
The format is expected to resemble the following example:
..code-block:: yaml
apiVersion: metalk8s.scality.com/v1alpha1
kind: SolutionsConfiguration
archives:
- /path/to/solution/archive.iso
active:
solution-name: X.Y.Z-suffix (or 'latest')
"""
try:
with open(SOLUTIONS_CONFIG_FILE, 'r') as fd:
content = yaml.safe_load(fd)
config = yaml.safe_load(fd)
except Exception as exc:
msg = 'Failed to load "{}": {}'.format(SOLUTIONS_CONFIG_FILE, str(exc))
raise CommandExecutionError(message=msg)

return content.get('archives', []) or []
if config.get('kind') != 'SolutionsConfiguration':
raise CommandExecutionError(
'Invalid `kind` in configuration ({}), '
'must be "SolutionsConfiguration"'.format(config.get('kind'))
)

if config.get('apiVersion') not in SUPPORTED_CONFIG_VERSIONS:
raise CommandExecutionError(
'Invalid `apiVersion` in configuration ({}), '
'must be one of: {}'.format(
config.get('apiVersion'),
', '.join(SUPPORTED_CONFIG_VERSIONS)
)
)

config.setdefault('archives', [])
config.setdefault('active', {})

return config


def register_solution_version(
Expand Down
33 changes: 14 additions & 19 deletions salt/_pillar/metalk8s_solutions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,41 +7,36 @@


def __virtual__():
if 'metalk8s_solutions.read_config' not in __salt__:
return False, "Failed to load 'metalk8s_solution' module."
return __virtualname__


def _load_solutions():
"""Load Solutions from ConfigMap and config file."""
errors = []
try:
deployed = __salt__['metalk8s_solutions.list_deployed']()
except KeyError:
return __utils__['pillar_utils.errors_to_dict']([
"Failed to load 'metalk8s_solutions' module."
config_data = __salt__['metalk8s_solutions.read_config']()
except (IOError, CommandExecutionError) as exc:
config_data = __utils__['pillar_utils.errors_to_dict']([
"Error when reading Solutions config file: {}".format(exc)
])

try:
deployed = __salt__['metalk8s_solutions.list_deployed']()
except Exception as exc:
deployed = {}
errors.append(
deployed = __utils__['pillar_utils.errors_to_dict']([
"Error when retrieving ConfigMap 'metalk8s-solutions': {}".format(
exc
)
)

try:
configured = __salt__['metalk8s_solutions.list_configured']()
except (IOError, CommandExecutionError) as exc:
configured = []
errors.append(
"Error when reading Solutions config file: {}".format(exc)
)
])

result = {
'configured': configured,
'config': config_data,
'deployed': deployed,
}

if errors:
result.update(__utils__['pillar_utils.errors_to_dict'](errors))
for key in result:
__utils__['pillar_utils.promote_errors'](result, key)

return result

Expand Down

0 comments on commit 18a2ac0

Please sign in to comment.