Merge "Introduce v2 docs"
This commit is contained in:
commit
65e292b93e
|
@ -133,12 +133,12 @@ class TestReleasesManifestController(api.BaseResource):
|
||||||
armada_obj = Manifest(
|
armada_obj = Manifest(
|
||||||
documents, target_manifest=target_manifest).get_manifest()
|
documents, target_manifest=target_manifest).get_manifest()
|
||||||
|
|
||||||
prefix = armada_obj.get(const.KEYWORD_ARMADA).get(const.KEYWORD_PREFIX)
|
prefix = armada_obj[const.KEYWORD_DATA][const.KEYWORD_PREFIX]
|
||||||
known_releases = [release[0] for release in tiller.list_charts()]
|
known_releases = [release[0] for release in tiller.list_charts()]
|
||||||
|
|
||||||
message = {'tests': {'passed': [], 'skipped': [], 'failed': []}}
|
message = {'tests': {'passed': [], 'skipped': [], 'failed': []}}
|
||||||
|
|
||||||
for group in armada_obj.get(const.KEYWORD_ARMADA).get(
|
for group in armada_obj.get(const.KEYWORD_DATA).get(
|
||||||
const.KEYWORD_GROUPS):
|
const.KEYWORD_GROUPS):
|
||||||
for ch in group.get(const.KEYWORD_CHARTS):
|
for ch in group.get(const.KEYWORD_CHARTS):
|
||||||
chart = ch['chart']
|
chart = ch['chart']
|
||||||
|
|
|
@ -126,13 +126,14 @@ class DeleteChartManifest(CliAction):
|
||||||
documents = list(yaml.safe_load_all(f.read()))
|
documents = list(yaml.safe_load_all(f.read()))
|
||||||
try:
|
try:
|
||||||
armada_obj = Manifest(documents).get_manifest()
|
armada_obj = Manifest(documents).get_manifest()
|
||||||
prefix = armada_obj.get(const.KEYWORD_ARMADA).get(
|
prefix = armada_obj.get(const.KEYWORD_DATA).get(
|
||||||
const.KEYWORD_PREFIX)
|
const.KEYWORD_PREFIX)
|
||||||
|
|
||||||
for group in armada_obj.get(const.KEYWORD_ARMADA).get(
|
for group in armada_obj.get(const.KEYWORD_DATA).get(
|
||||||
const.KEYWORD_GROUPS):
|
const.KEYWORD_GROUPS):
|
||||||
for ch in group.get(const.KEYWORD_CHARTS):
|
for ch in group.get(const.KEYWORD_DATA).get(
|
||||||
chart = ch.get('chart')
|
const.KEYWORD_CHARTS):
|
||||||
|
chart = ch.get(const.KEYWORD_DATA)
|
||||||
release_name = release_prefixer(
|
release_name = release_prefixer(
|
||||||
prefix, chart.get('release'))
|
prefix, chart.get('release'))
|
||||||
if release_name in known_release_names:
|
if release_name in known_release_names:
|
||||||
|
|
|
@ -147,10 +147,10 @@ class TestChartManifest(CliAction):
|
||||||
armada_obj = Manifest(
|
armada_obj = Manifest(
|
||||||
documents,
|
documents,
|
||||||
target_manifest=self.target_manifest).get_manifest()
|
target_manifest=self.target_manifest).get_manifest()
|
||||||
prefix = armada_obj.get(const.KEYWORD_ARMADA).get(
|
prefix = armada_obj.get(const.KEYWORD_DATA).get(
|
||||||
const.KEYWORD_PREFIX)
|
const.KEYWORD_PREFIX)
|
||||||
|
|
||||||
for group in armada_obj.get(const.KEYWORD_ARMADA).get(
|
for group in armada_obj.get(const.KEYWORD_DATA).get(
|
||||||
const.KEYWORD_GROUPS):
|
const.KEYWORD_GROUPS):
|
||||||
for ch in group.get(const.KEYWORD_CHARTS):
|
for ch in group.get(const.KEYWORD_CHARTS):
|
||||||
chart = ch['chart']
|
chart = ch['chart']
|
||||||
|
|
|
@ -88,7 +88,7 @@ class ChartDeployAwareLogger(logging.Logger):
|
||||||
def _log(self, level, msg, *args, **kwargs):
|
def _log(self, level, msg, *args, **kwargs):
|
||||||
chart = get_current_chart()
|
chart = get_current_chart()
|
||||||
if chart:
|
if chart:
|
||||||
name = chart['chart_name']
|
name = chart['metadata']['name']
|
||||||
prefix = '[chart={}]: '.format(name)
|
prefix = '[chart={}]: '.format(name)
|
||||||
else:
|
else:
|
||||||
prefix = ''
|
prefix = ''
|
||||||
|
|
|
@ -12,11 +12,8 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# Documents
|
# Keywords
|
||||||
DOCUMENT_CHART = 'armada/Chart/v1'
|
KEYWORD_DATA = 'data'
|
||||||
DOCUMENT_GROUP = 'armada/ChartGroup/v1'
|
|
||||||
DOCUMENT_MANIFEST = 'armada/Manifest/v1'
|
|
||||||
KEYWORD_ARMADA = 'armada'
|
|
||||||
KEYWORD_PREFIX = 'release_prefix'
|
KEYWORD_PREFIX = 'release_prefix'
|
||||||
KEYWORD_GROUPS = 'chart_groups'
|
KEYWORD_GROUPS = 'chart_groups'
|
||||||
KEYWORD_CHARTS = 'chart_group'
|
KEYWORD_CHARTS = 'chart_group'
|
||||||
|
|
|
@ -104,13 +104,14 @@ class Armada(object):
|
||||||
raise tiller_exceptions.TillerServicesUnavailableException()
|
raise tiller_exceptions.TillerServicesUnavailableException()
|
||||||
|
|
||||||
# Clone the chart sources
|
# Clone the chart sources
|
||||||
manifest_data = self.manifest.get(const.KEYWORD_ARMADA, {})
|
manifest_data = self.manifest.get(const.KEYWORD_DATA, {})
|
||||||
for group in manifest_data.get(const.KEYWORD_GROUPS, []):
|
for group in manifest_data.get(const.KEYWORD_GROUPS, []):
|
||||||
for ch in group.get(const.KEYWORD_CHARTS, []):
|
for ch in group.get(const.KEYWORD_DATA).get(
|
||||||
|
const.KEYWORD_CHARTS, []):
|
||||||
self.get_chart(ch)
|
self.get_chart(ch)
|
||||||
|
|
||||||
def get_chart(self, ch):
|
def get_chart(self, ch):
|
||||||
chart = ch.get('chart', {})
|
chart = ch.get(const.KEYWORD_DATA)
|
||||||
chart_source = chart.get('source', {})
|
chart_source = chart.get('source', {})
|
||||||
location = chart_source.get('location')
|
location = chart_source.get('location')
|
||||||
ct_type = chart_source.get('type')
|
ct_type = chart_source.get('type')
|
||||||
|
@ -158,10 +159,10 @@ class Armada(object):
|
||||||
self.chart_cache[source_key] = repo_dir
|
self.chart_cache[source_key] = repo_dir
|
||||||
chart['source_dir'] = (self.chart_cache.get(source_key), subpath)
|
chart['source_dir'] = (self.chart_cache.get(source_key), subpath)
|
||||||
else:
|
else:
|
||||||
chart_name = chart.get('chart_name')
|
name = chart['metadata']['name']
|
||||||
raise source_exceptions.ChartSourceException(ct_type, chart_name)
|
raise source_exceptions.ChartSourceException(ct_type, name)
|
||||||
|
|
||||||
for dep in ch.get('chart', {}).get('dependencies', []):
|
for dep in ch.get(const.KEYWORD_DATA, {}).get('dependencies', []):
|
||||||
self.get_chart(dep)
|
self.get_chart(dep)
|
||||||
|
|
||||||
def sync(self):
|
def sync(self):
|
||||||
|
@ -185,11 +186,12 @@ class Armada(object):
|
||||||
|
|
||||||
known_releases = self.tiller.list_releases()
|
known_releases = self.tiller.list_releases()
|
||||||
|
|
||||||
manifest_data = self.manifest.get(const.KEYWORD_ARMADA, {})
|
manifest_data = self.manifest.get(const.KEYWORD_DATA, {})
|
||||||
prefix = manifest_data.get(const.KEYWORD_PREFIX)
|
prefix = manifest_data.get(const.KEYWORD_PREFIX)
|
||||||
|
|
||||||
for chartgroup in manifest_data.get(const.KEYWORD_GROUPS, []):
|
for cg in manifest_data.get(const.KEYWORD_GROUPS, []):
|
||||||
cg_name = chartgroup.get('name', '<missing name>')
|
chartgroup = cg.get(const.KEYWORD_DATA)
|
||||||
|
cg_name = cg.get('metadata').get('name')
|
||||||
cg_desc = chartgroup.get('description', '<missing description>')
|
cg_desc = chartgroup.get('description', '<missing description>')
|
||||||
cg_sequenced = chartgroup.get('sequenced',
|
cg_sequenced = chartgroup.get('sequenced',
|
||||||
False) or self.force_wait
|
False) or self.force_wait
|
||||||
|
@ -198,11 +200,10 @@ class Armada(object):
|
||||||
cg_desc, cg_sequenced,
|
cg_desc, cg_sequenced,
|
||||||
' (forced)' if self.force_wait else '')
|
' (forced)' if self.force_wait else '')
|
||||||
|
|
||||||
# TODO(MarshM): Deprecate the `test_charts` key
|
# TODO: Remove when v1 doc support is removed.
|
||||||
cg_test_all_charts = chartgroup.get('test_charts')
|
cg_test_all_charts = chartgroup.get('test_charts')
|
||||||
|
|
||||||
cg_charts = chartgroup.get(const.KEYWORD_CHARTS, [])
|
cg_charts = chartgroup.get(const.KEYWORD_CHARTS, [])
|
||||||
charts = map(lambda x: x.get('chart', {}), cg_charts)
|
|
||||||
|
|
||||||
def deploy_chart(chart):
|
def deploy_chart(chart):
|
||||||
set_current_chart(chart)
|
set_current_chart(chart)
|
||||||
|
@ -217,7 +218,7 @@ class Armada(object):
|
||||||
|
|
||||||
# Returns whether or not there was a failure
|
# Returns whether or not there was a failure
|
||||||
def handle_result(chart, get_result):
|
def handle_result(chart, get_result):
|
||||||
name = chart['chart_name']
|
name = chart['metadata']['name']
|
||||||
try:
|
try:
|
||||||
result = get_result()
|
result = get_result()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
@ -229,7 +230,7 @@ class Armada(object):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if cg_sequenced:
|
if cg_sequenced:
|
||||||
for chart in charts:
|
for chart in cg_charts:
|
||||||
if (handle_result(chart, lambda: deploy_chart(chart))):
|
if (handle_result(chart, lambda: deploy_chart(chart))):
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
@ -237,7 +238,7 @@ class Armada(object):
|
||||||
max_workers=len(cg_charts)) as executor:
|
max_workers=len(cg_charts)) as executor:
|
||||||
future_to_chart = {
|
future_to_chart = {
|
||||||
executor.submit(deploy_chart, chart): chart
|
executor.submit(deploy_chart, chart): chart
|
||||||
for chart in charts
|
for chart in cg_charts
|
||||||
}
|
}
|
||||||
|
|
||||||
for future in as_completed(future_to_chart):
|
for future in as_completed(future_to_chart):
|
||||||
|
@ -260,7 +261,7 @@ class Armada(object):
|
||||||
if self.enable_chart_cleanup:
|
if self.enable_chart_cleanup:
|
||||||
self._chart_cleanup(
|
self._chart_cleanup(
|
||||||
prefix,
|
prefix,
|
||||||
self.manifest[const.KEYWORD_ARMADA][const.KEYWORD_GROUPS], msg)
|
self.manifest[const.KEYWORD_DATA][const.KEYWORD_GROUPS], msg)
|
||||||
|
|
||||||
LOG.info('Done applying manifest.')
|
LOG.info('Done applying manifest.')
|
||||||
return msg
|
return msg
|
||||||
|
|
|
@ -41,7 +41,8 @@ class ChartDeploy(object):
|
||||||
self.timeout = timeout
|
self.timeout = timeout
|
||||||
self.tiller = tiller
|
self.tiller = tiller
|
||||||
|
|
||||||
def execute(self, chart, cg_test_all_charts, prefix, known_releases):
|
def execute(self, ch, cg_test_all_charts, prefix, known_releases):
|
||||||
|
chart = ch[const.KEYWORD_DATA]
|
||||||
namespace = chart.get('namespace')
|
namespace = chart.get('namespace')
|
||||||
release = chart.get('release')
|
release = chart.get('release')
|
||||||
release_name = r.release_prefixer(prefix, release)
|
release_name = r.release_prefixer(prefix, release)
|
||||||
|
@ -73,7 +74,7 @@ class ChartDeploy(object):
|
||||||
# Begin Chart timeout deadline
|
# Begin Chart timeout deadline
|
||||||
deadline = time.time() + chart_wait.get_timeout()
|
deadline = time.time() + chart_wait.get_timeout()
|
||||||
|
|
||||||
chartbuilder = ChartBuilder(chart)
|
chartbuilder = ChartBuilder(ch)
|
||||||
new_chart = chartbuilder.get_helm_chart()
|
new_chart = chartbuilder.get_helm_chart()
|
||||||
|
|
||||||
# TODO(mark-burnett): It may be more robust to directly call
|
# TODO(mark-burnett): It may be more robust to directly call
|
||||||
|
|
|
@ -25,6 +25,7 @@ from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
from armada.exceptions import chartbuilder_exceptions
|
from armada.exceptions import chartbuilder_exceptions
|
||||||
|
from armada import const
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -49,6 +50,7 @@ class ChartBuilder(object):
|
||||||
|
|
||||||
# store chart schema
|
# store chart schema
|
||||||
self.chart = chart
|
self.chart = chart
|
||||||
|
self.chart_data = chart[const.KEYWORD_DATA]
|
||||||
|
|
||||||
# extract, pull, whatever the chart from its source
|
# extract, pull, whatever the chart from its source
|
||||||
self.source_directory = self.get_source_path()
|
self.source_directory = self.get_source_path()
|
||||||
|
@ -62,7 +64,7 @@ class ChartBuilder(object):
|
||||||
Returns "<source directory>/<subpath>" taken from the "source_dir"
|
Returns "<source directory>/<subpath>" taken from the "source_dir"
|
||||||
property from the chart, or else "" if the property isn't a 2-tuple.
|
property from the chart, or else "" if the property isn't a 2-tuple.
|
||||||
'''
|
'''
|
||||||
source_dir = self.chart.get('source_dir')
|
source_dir = self.chart_data.get('source_dir')
|
||||||
return (os.path.join(*source_dir) if
|
return (os.path.join(*source_dir) if
|
||||||
(source_dir and isinstance(source_dir, (list, tuple)) and
|
(source_dir and isinstance(source_dir, (list, tuple)) and
|
||||||
len(source_dir) == 2) else "")
|
len(source_dir) == 2) else "")
|
||||||
|
@ -206,7 +208,7 @@ class ChartBuilder(object):
|
||||||
Process all files in templates/ as a template to attach to the chart,
|
Process all files in templates/ as a template to attach to the chart,
|
||||||
building a :class:`hapi.chart.template_pb2.Template` object.
|
building a :class:`hapi.chart.template_pb2.Template` object.
|
||||||
'''
|
'''
|
||||||
chart_name = self.chart.get('chart_name')
|
chart_name = self.chart['metadata']['name']
|
||||||
templates = []
|
templates = []
|
||||||
if not os.path.exists(
|
if not os.path.exists(
|
||||||
os.path.join(self.source_directory, 'templates')):
|
os.path.join(self.source_directory, 'templates')):
|
||||||
|
@ -240,12 +242,11 @@ class ChartBuilder(object):
|
||||||
return self._helm_chart
|
return self._helm_chart
|
||||||
|
|
||||||
dependencies = []
|
dependencies = []
|
||||||
chart_dependencies = self.chart.get('dependencies', [])
|
chart_dependencies = self.chart_data.get('dependencies', [])
|
||||||
chart_name = self.chart.get('chart_name', None)
|
chart_name = self.chart['metadata']['name']
|
||||||
chart_release = self.chart.get('release', None)
|
chart_release = self.chart_data.get('release', None)
|
||||||
for dep in chart_dependencies:
|
for dep_chart in chart_dependencies:
|
||||||
dep_chart = dep.get('chart', {})
|
dep_chart_name = dep_chart['metadata']['name']
|
||||||
dep_chart_name = dep_chart.get('chart_name', None)
|
|
||||||
LOG.info("Building dependency chart %s for release %s.",
|
LOG.info("Building dependency chart %s for release %s.",
|
||||||
dep_chart_name, chart_release)
|
dep_chart_name, chart_release)
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -17,6 +17,7 @@ from oslo_log import log as logging
|
||||||
|
|
||||||
from armada import const
|
from armada import const
|
||||||
from armada import exceptions
|
from armada import exceptions
|
||||||
|
from armada.handlers import schema
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -62,10 +63,10 @@ class Manifest(object):
|
||||||
self.manifest = manifests[0] if manifests else None
|
self.manifest = manifests[0] if manifests else None
|
||||||
|
|
||||||
if not all([self.charts, self.groups, self.manifest]):
|
if not all([self.charts, self.groups, self.manifest]):
|
||||||
expected_schemas = [const.DOCUMENT_CHART, const.DOCUMENT_GROUP]
|
expected_schemas = [schema.TYPE_CHART, schema.TYPE_CHARTGROUP]
|
||||||
error = ('Documents must be a list of documents with at least one '
|
error = ('Documents must include at least one of each of {} '
|
||||||
'of each of the following schemas: %s and only one '
|
'and only one {}').format(expected_schemas,
|
||||||
'manifest' % expected_schemas)
|
schema.TYPE_MANIFEST)
|
||||||
LOG.error(error)
|
LOG.error(error)
|
||||||
raise exceptions.ManifestException(details=error)
|
raise exceptions.ManifestException(details=error)
|
||||||
|
|
||||||
|
@ -87,11 +88,14 @@ class Manifest(object):
|
||||||
groups = []
|
groups = []
|
||||||
manifests = []
|
manifests = []
|
||||||
for document in self.documents:
|
for document in self.documents:
|
||||||
if document.get('schema') == const.DOCUMENT_CHART:
|
schema_info = schema.get_schema_info(document.get('schema'))
|
||||||
|
if not schema_info:
|
||||||
|
continue
|
||||||
|
if schema_info.type == schema.TYPE_CHART:
|
||||||
charts.append(document)
|
charts.append(document)
|
||||||
if document.get('schema') == const.DOCUMENT_GROUP:
|
if schema_info.type == schema.TYPE_CHARTGROUP:
|
||||||
groups.append(document)
|
groups.append(document)
|
||||||
if document.get('schema') == const.DOCUMENT_MANIFEST:
|
if schema_info.type == schema.TYPE_MANIFEST:
|
||||||
manifest_name = document.get('metadata', {}).get('name')
|
manifest_name = document.get('metadata', {}).get('name')
|
||||||
if target_manifest:
|
if target_manifest:
|
||||||
if manifest_name == target_manifest:
|
if manifest_name == target_manifest:
|
||||||
|
@ -113,8 +117,8 @@ class Manifest(object):
|
||||||
if chart.get('metadata', {}).get('name') == name:
|
if chart.get('metadata', {}).get('name') == name:
|
||||||
return chart
|
return chart
|
||||||
raise exceptions.BuildChartException(
|
raise exceptions.BuildChartException(
|
||||||
details='Could not build {} named "{}"'.format(
|
details='Could not find {} named "{}"'.format(
|
||||||
const.DOCUMENT_CHART, name))
|
schema.TYPE_CHART, name))
|
||||||
|
|
||||||
def find_chart_group_document(self, name):
|
def find_chart_group_document(self, name):
|
||||||
"""Returns a chart group document with the specified name
|
"""Returns a chart group document with the specified name
|
||||||
|
@ -129,8 +133,8 @@ class Manifest(object):
|
||||||
if group.get('metadata', {}).get('name') == name:
|
if group.get('metadata', {}).get('name') == name:
|
||||||
return group
|
return group
|
||||||
raise exceptions.BuildChartGroupException(
|
raise exceptions.BuildChartGroupException(
|
||||||
details='Could not build {} named "{}"'.format(
|
details='Could not find {} named "{}"'.format(
|
||||||
const.DOCUMENT_GROUP, name))
|
schema.TYPE_CHARTGROUP, name))
|
||||||
|
|
||||||
def build_chart_deps(self, chart):
|
def build_chart_deps(self, chart):
|
||||||
"""Recursively build chart dependencies for ``chart``.
|
"""Recursively build chart dependencies for ``chart``.
|
||||||
|
@ -143,20 +147,19 @@ class Manifest(object):
|
||||||
under ``chart['data']['dependencies']`` could not be found.
|
under ``chart['data']['dependencies']`` could not be found.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
chart_dependencies = chart.get('data', {}).get('dependencies', [])
|
chart_dependencies = chart.get(const.KEYWORD_DATA, {}).get(
|
||||||
|
'dependencies', [])
|
||||||
for iter, dep in enumerate(chart_dependencies):
|
for iter, dep in enumerate(chart_dependencies):
|
||||||
if isinstance(dep, dict):
|
if isinstance(dep, dict):
|
||||||
continue
|
continue
|
||||||
chart_dep = self.find_chart_document(dep)
|
chart_dep = self.find_chart_document(dep)
|
||||||
self.build_chart_deps(chart_dep)
|
self.build_chart_deps(chart_dep)
|
||||||
chart['data']['dependencies'][iter] = {
|
chart[const.KEYWORD_DATA]['dependencies'][iter] = chart_dep
|
||||||
'chart': chart_dep.get('data', {})
|
|
||||||
}
|
|
||||||
except Exception:
|
except Exception:
|
||||||
raise exceptions.ChartDependencyException(
|
raise exceptions.ChartDependencyException(
|
||||||
details="Could not build dependencies for chart {} in {}".
|
details='Could not build dependencies for {} named "{}"'.
|
||||||
format(
|
format(schema.TYPE_CHART,
|
||||||
chart.get('metadata').get('name'), const.DOCUMENT_CHART))
|
chart.get('metadata').get('name')))
|
||||||
else:
|
else:
|
||||||
return chart
|
return chart
|
||||||
|
|
||||||
|
@ -173,19 +176,19 @@ class Manifest(object):
|
||||||
try:
|
try:
|
||||||
chart = None
|
chart = None
|
||||||
for iter, chart in enumerate(
|
for iter, chart in enumerate(
|
||||||
chart_group.get('data', {}).get('chart_group', [])):
|
chart_group.get(const.KEYWORD_DATA).get(
|
||||||
|
const.KEYWORD_CHARTS, [])):
|
||||||
if isinstance(chart, dict):
|
if isinstance(chart, dict):
|
||||||
continue
|
continue
|
||||||
chart_dep = self.find_chart_document(chart)
|
chart_object = self.find_chart_document(chart)
|
||||||
self.build_chart_deps(chart_dep)
|
self.build_chart_deps(chart_object)
|
||||||
chart_group['data']['chart_group'][iter] = {
|
chart_group[const.KEYWORD_DATA][const.KEYWORD_CHARTS][iter] = \
|
||||||
'chart': chart_dep.get('data', {})
|
chart_object
|
||||||
}
|
|
||||||
except exceptions.ManifestException:
|
except exceptions.ManifestException:
|
||||||
cg_name = chart_group.get('metadata', {}).get('name')
|
cg_name = chart_group.get('metadata', {}).get('name')
|
||||||
raise exceptions.BuildChartGroupException(
|
raise exceptions.BuildChartGroupException(
|
||||||
details="Could not build chart group {} in {}".format(
|
details='Could not build {} named "{}"'.format(
|
||||||
cg_name, const.DOCUMENT_GROUP))
|
schema.TYPE_CHARTGROUP, cg_name))
|
||||||
|
|
||||||
return chart_group
|
return chart_group
|
||||||
|
|
||||||
|
@ -196,20 +199,18 @@ class Manifest(object):
|
||||||
:returns: The Armada manifest with the data of the chart groups.
|
:returns: The Armada manifest with the data of the chart groups.
|
||||||
:rtype: dict
|
:rtype: dict
|
||||||
:raises ManifestException: If a chart group's data listed
|
:raises ManifestException: If a chart group's data listed
|
||||||
under ``chart_group['data']`` could not be found.
|
under ``chart_group[const.KEYWORD_DATA]`` could not be found.
|
||||||
"""
|
"""
|
||||||
for iter, group in enumerate(
|
for iter, group in enumerate(
|
||||||
self.manifest.get('data', {}).get('chart_groups', [])):
|
self.manifest.get(const.KEYWORD_DATA, {}).get(
|
||||||
|
const.KEYWORD_GROUPS, [])):
|
||||||
if isinstance(group, dict):
|
if isinstance(group, dict):
|
||||||
continue
|
continue
|
||||||
chart_grp = self.find_chart_group_document(group)
|
chart_grp = self.find_chart_group_document(group)
|
||||||
self.build_chart_group(chart_grp)
|
self.build_chart_group(chart_grp)
|
||||||
|
|
||||||
# Add name to chart group
|
self.manifest[const.KEYWORD_DATA][const.KEYWORD_GROUPS][iter] = \
|
||||||
ch_grp_data = chart_grp.get('data', {})
|
chart_grp
|
||||||
ch_grp_data['name'] = chart_grp.get('metadata', {}).get('name')
|
|
||||||
|
|
||||||
self.manifest['data']['chart_groups'][iter] = ch_grp_data
|
|
||||||
|
|
||||||
return self.manifest
|
return self.manifest
|
||||||
|
|
||||||
|
@ -221,4 +222,4 @@ class Manifest(object):
|
||||||
"""
|
"""
|
||||||
self.build_armada_manifest()
|
self.build_armada_manifest()
|
||||||
|
|
||||||
return {'armada': self.manifest.get('data', {})}
|
return self.manifest
|
||||||
|
|
|
@ -16,9 +16,9 @@ import collections
|
||||||
import json
|
import json
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
from armada import const
|
|
||||||
from armada.exceptions import override_exceptions
|
from armada.exceptions import override_exceptions
|
||||||
from armada.exceptions import validate_exceptions
|
from armada.exceptions import validate_exceptions
|
||||||
|
from armada.handlers import schema
|
||||||
from armada.utils import validate
|
from armada.utils import validate
|
||||||
|
|
||||||
|
|
||||||
|
@ -65,17 +65,18 @@ class Override(object):
|
||||||
|
|
||||||
def find_document_type(self, alias):
|
def find_document_type(self, alias):
|
||||||
if alias == 'chart_group':
|
if alias == 'chart_group':
|
||||||
return const.DOCUMENT_GROUP
|
return schema.TYPE_CHARTGROUP
|
||||||
if alias == 'chart':
|
if alias == 'chart':
|
||||||
return const.DOCUMENT_CHART
|
return schema.TYPE_CHART
|
||||||
if alias == 'manifest':
|
if alias == 'manifest':
|
||||||
return const.DOCUMENT_MANIFEST
|
return schema.TYPE_MANIFEST
|
||||||
else:
|
else:
|
||||||
raise ValueError("Could not find {} document".format(alias))
|
raise ValueError("Could not find {} document".format(alias))
|
||||||
|
|
||||||
def find_manifest_document(self, doc_path):
|
def find_manifest_document(self, doc_path):
|
||||||
for doc in self.documents:
|
for doc in self.documents:
|
||||||
if doc.get('schema') == self.find_document_type(
|
schema_info = schema.get_schema_info(doc.get('schema'))
|
||||||
|
if schema_info.type == self.find_document_type(
|
||||||
doc_path[0]) and doc.get('metadata',
|
doc_path[0]) and doc.get('metadata',
|
||||||
{}).get('name') == doc_path[1]:
|
{}).get('name') == doc_path[1]:
|
||||||
return doc
|
return doc
|
||||||
|
@ -121,45 +122,29 @@ class Override(object):
|
||||||
new_data = self.array_to_dict(data_path, new_value)
|
new_data = self.array_to_dict(data_path, new_value)
|
||||||
self.update(document.get('data', {}), new_data)
|
self.update(document.get('data', {}), new_data)
|
||||||
|
|
||||||
def update_document(self, merging_values):
|
def update_documents(self, merging_values):
|
||||||
for doc in merging_values:
|
for doc in merging_values:
|
||||||
if doc.get('schema') == const.DOCUMENT_CHART:
|
self.update_document(doc)
|
||||||
self.update_chart_document(doc)
|
|
||||||
if doc.get('schema') == const.DOCUMENT_GROUP:
|
|
||||||
self.update_chart_group_document(doc)
|
|
||||||
if doc.get('schema') == const.DOCUMENT_MANIFEST:
|
|
||||||
self.update_armada_manifest(doc)
|
|
||||||
|
|
||||||
def update_chart_document(self, ovr):
|
def update_document(self, ovr):
|
||||||
for doc in self.documents:
|
ovr_schema_info = schema.get_schema_info(ovr.get('schema'))
|
||||||
if doc.get('schema') == const.DOCUMENT_CHART and doc.get(
|
if ovr_schema_info:
|
||||||
'metadata', {}).get('name') == ovr.get('metadata',
|
for doc in self.documents:
|
||||||
{}).get('name'):
|
schema_info = schema.get_schema_info(doc.get('schema'))
|
||||||
self.update(doc.get('data', {}), ovr.get('data', {}))
|
if schema_info:
|
||||||
return
|
if schema_info == ovr_schema_info:
|
||||||
|
if doc['metadata']['name'] == ovr['metadata']['name']:
|
||||||
def update_chart_group_document(self, ovr):
|
data = doc.get('data', {})
|
||||||
for doc in self.documents:
|
ovr_data = ovr.get('data', {})
|
||||||
if doc.get('schema') == const.DOCUMENT_GROUP and doc.get(
|
self.update(data, ovr_data)
|
||||||
'metadata', {}).get('name') == ovr.get('metadata',
|
return
|
||||||
{}).get('name'):
|
|
||||||
self.update(doc.get('data', {}), ovr.get('data', {}))
|
|
||||||
return
|
|
||||||
|
|
||||||
def update_armada_manifest(self, ovr):
|
|
||||||
for doc in self.documents:
|
|
||||||
if doc.get('schema') == const.DOCUMENT_MANIFEST and doc.get(
|
|
||||||
'metadata', {}).get('name') == ovr.get('metadata',
|
|
||||||
{}).get('name'):
|
|
||||||
self.update(doc.get('data', {}), ovr.get('data', {}))
|
|
||||||
return
|
|
||||||
|
|
||||||
def update_manifests(self):
|
def update_manifests(self):
|
||||||
|
|
||||||
if self.values:
|
if self.values:
|
||||||
for value in self.values:
|
for value in self.values:
|
||||||
merging_values = self._load_yaml_file(value)
|
merging_values = self._load_yaml_file(value)
|
||||||
self.update_document(merging_values)
|
self.update_documents(merging_values)
|
||||||
# Validate document with updated values
|
# Validate document with updated values
|
||||||
self._document_checker(self.documents, self.values)
|
self._document_checker(self.documents, self.values)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,80 @@
|
||||||
|
# Copyright 2019 The Armada Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import os
|
||||||
|
import pkg_resources
|
||||||
|
import re
|
||||||
|
import yaml
|
||||||
|
|
||||||
|
# Types
|
||||||
|
TYPE_CHART = 'Chart'
|
||||||
|
TYPE_CHARTGROUP = 'ChartGroup'
|
||||||
|
TYPE_MANIFEST = 'Manifest'
|
||||||
|
|
||||||
|
# Versions
|
||||||
|
VERSION_FORMAT = r'^v(\d+)$'
|
||||||
|
VERSION_MIN = 1
|
||||||
|
VERSION_MAX = 2
|
||||||
|
|
||||||
|
# Creates a mapping between ``metadata.name``: ``data`` where the
|
||||||
|
# ``metadata.name`` is the ``schema`` of a manifest and the ``data`` is the
|
||||||
|
# JSON schema to be used to validate the manifest in question.
|
||||||
|
_SCHEMAS = {}
|
||||||
|
|
||||||
|
|
||||||
|
class SchemaInfo(object):
|
||||||
|
|
||||||
|
def __init__(self, type, version, data):
|
||||||
|
self.type = type
|
||||||
|
self.version = version
|
||||||
|
self.data = data
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.type == other.type and self.version == other.version
|
||||||
|
|
||||||
|
|
||||||
|
def get_schema_info(name):
|
||||||
|
return _SCHEMAS.get(name)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_schema_info(name, data):
|
||||||
|
parts = name.split('/')
|
||||||
|
prefix, type, version_string = parts
|
||||||
|
version_match = re.search(VERSION_FORMAT, version_string)
|
||||||
|
version = int(version_match.group(1))
|
||||||
|
return SchemaInfo(type, version, data)
|
||||||
|
|
||||||
|
|
||||||
|
def _get_schema_dir():
|
||||||
|
return pkg_resources.resource_filename('armada', 'schemas')
|
||||||
|
|
||||||
|
|
||||||
|
def _load_schemas():
|
||||||
|
"""Populates ``_SCHEMAS`` with the schemas defined in package
|
||||||
|
``armada.schemas``.
|
||||||
|
|
||||||
|
"""
|
||||||
|
schema_dir = _get_schema_dir()
|
||||||
|
for schema_file in os.listdir(schema_dir):
|
||||||
|
with open(os.path.join(schema_dir, schema_file)) as f:
|
||||||
|
for schema in yaml.safe_load_all(f):
|
||||||
|
name = schema['metadata']['name']
|
||||||
|
if name in _SCHEMAS:
|
||||||
|
raise RuntimeError(
|
||||||
|
'Duplicate schema specified for: %s.' % name)
|
||||||
|
_SCHEMAS[name] = _get_schema_info(name, schema['data'])
|
||||||
|
|
||||||
|
|
||||||
|
# Fill the cache.
|
||||||
|
_load_schemas()
|
|
@ -60,9 +60,7 @@ class Test(object):
|
||||||
|
|
||||||
self.timeout = const.DEFAULT_TEST_TIMEOUT
|
self.timeout = const.DEFAULT_TEST_TIMEOUT
|
||||||
|
|
||||||
# NOTE(drewwalters96): Support the chart_group `test_charts` key until
|
# TODO: Remove when v1 doc support is removed.
|
||||||
# its deprecation period ends. The `test.enabled`, `enable_all` flag,
|
|
||||||
# and deprecated, boolean `test` key override this value if provided.
|
|
||||||
if cg_test_charts is not None:
|
if cg_test_charts is not None:
|
||||||
LOG.warn('Chart group key `test_charts` is deprecated and will be '
|
LOG.warn('Chart group key `test_charts` is deprecated and will be '
|
||||||
'removed. Use `test.enabled` instead.')
|
'removed. Use `test.enabled` instead.')
|
||||||
|
@ -70,7 +68,7 @@ class Test(object):
|
||||||
else:
|
else:
|
||||||
self.test_enabled = True
|
self.test_enabled = True
|
||||||
|
|
||||||
# NOTE: Support old, boolean `test` key until deprecation period ends.
|
# TODO: Remove when v1 doc support is removed.
|
||||||
if (type(test_values) == bool):
|
if (type(test_values) == bool):
|
||||||
LOG.warn('Boolean value for chart `test` key is deprecated and '
|
LOG.warn('Boolean value for chart `test` key is deprecated and '
|
||||||
'will be removed. Use `test.enabled` instead.')
|
'will be removed. Use `test.enabled` instead.')
|
||||||
|
|
|
@ -30,8 +30,10 @@ from oslo_config import cfg
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
from armada import const
|
from armada import const
|
||||||
|
from armada.conf import get_current_chart
|
||||||
from armada.exceptions import tiller_exceptions as ex
|
from armada.exceptions import tiller_exceptions as ex
|
||||||
from armada.handlers.k8s import K8s
|
from armada.handlers.k8s import K8s
|
||||||
|
from armada.handlers import schema
|
||||||
from armada.utils import helm
|
from armada.utils import helm
|
||||||
from armada.utils.release import label_selectors, get_release_status
|
from armada.utils.release import label_selectors, get_release_status
|
||||||
|
|
||||||
|
@ -303,6 +305,7 @@ class Tiller(object):
|
||||||
:param namespace: name of pod for actions
|
:param namespace: name of pod for actions
|
||||||
'''
|
'''
|
||||||
|
|
||||||
|
# TODO: Remove when v1 doc support is removed.
|
||||||
try:
|
try:
|
||||||
for action in actions.get('update', []):
|
for action in actions.get('update', []):
|
||||||
name = action.get('name')
|
name = action.get('name')
|
||||||
|
@ -667,15 +670,20 @@ class Tiller(object):
|
||||||
self.k8s.delete_job_action(jb_name, namespace, timeout=timeout)
|
self.k8s.delete_job_action(jb_name, namespace, timeout=timeout)
|
||||||
handled = True
|
handled = True
|
||||||
|
|
||||||
if resource_type == 'cronjob' or resource_type == 'job':
|
# TODO: Remove when v1 doc support is removed.
|
||||||
|
chart = get_current_chart()
|
||||||
|
schema_info = schema.get_schema_info(chart['schema'])
|
||||||
|
job_implies_cronjob = schema_info.version < 2
|
||||||
|
implied_cronjob = resource_type == 'job' and job_implies_cronjob
|
||||||
|
|
||||||
|
if resource_type == 'cronjob' or implied_cronjob:
|
||||||
get_jobs = self.k8s.get_namespace_cron_job(
|
get_jobs = self.k8s.get_namespace_cron_job(
|
||||||
namespace, label_selector=label_selector)
|
namespace, label_selector=label_selector)
|
||||||
for jb in get_jobs.items:
|
for jb in get_jobs.items:
|
||||||
jb_name = jb.metadata.name
|
jb_name = jb.metadata.name
|
||||||
|
|
||||||
if resource_type == 'job':
|
# TODO: Remove when v1 doc support is removed.
|
||||||
# TODO: Eventually disallow this, allowing initially since
|
if implied_cronjob:
|
||||||
# some existing clients were expecting this behavior.
|
|
||||||
LOG.warn("Deleting cronjobs via `type: job` is "
|
LOG.warn("Deleting cronjobs via `type: job` is "
|
||||||
"deprecated, use `type: cronjob` instead")
|
"deprecated, use `type: cronjob` instead")
|
||||||
|
|
||||||
|
@ -726,7 +734,7 @@ class Tiller(object):
|
||||||
values,
|
values,
|
||||||
timeout=const.DEFAULT_TILLER_TIMEOUT):
|
timeout=const.DEFAULT_TILLER_TIMEOUT):
|
||||||
'''
|
'''
|
||||||
update statefullsets (daemon, stateful)
|
update statefulsets (daemon, stateful)
|
||||||
'''
|
'''
|
||||||
|
|
||||||
if action_type == 'daemonset':
|
if action_type == 'daemonset':
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# JSON schema for validating Armada charts.
|
# NOTE: Do not modify this schema, it is deprecated.
|
||||||
---
|
---
|
||||||
schema: deckhand/DataSchema/v1
|
schema: deckhand/DataSchema/v1
|
||||||
metadata:
|
metadata:
|
||||||
|
@ -60,7 +60,6 @@ data:
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
test:
|
test:
|
||||||
anyOf:
|
anyOf:
|
||||||
# TODO: Remove boolean support after deprecation period.
|
|
||||||
- type: boolean
|
- type: boolean
|
||||||
- type: object
|
- type: object
|
||||||
properties:
|
properties:
|
||||||
|
@ -75,7 +74,6 @@ data:
|
||||||
type: boolean
|
type: boolean
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
additionalProperties: false
|
additionalProperties: false
|
||||||
# TODO(MarshM): Deprecate this `timeout` in favor of `wait.timeout`
|
|
||||||
timeout:
|
timeout:
|
||||||
type: integer
|
type: integer
|
||||||
wait:
|
wait:
|
||||||
|
@ -153,8 +151,6 @@ data:
|
||||||
$ref: '#/definitions/hook_action'
|
$ref: '#/definitions/hook_action'
|
||||||
create:
|
create:
|
||||||
$ref: '#/definitions/hook_action'
|
$ref: '#/definitions/hook_action'
|
||||||
# TODO(drewwalters96): Armada ignores post-update actions. Remove them
|
|
||||||
# in future schemas.
|
|
||||||
post:
|
post:
|
||||||
type: object
|
type: object
|
||||||
additionalProperties: false
|
additionalProperties: false
|
|
@ -0,0 +1,151 @@
|
||||||
|
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# JSON schema for validating Armada charts.
|
||||||
|
---
|
||||||
|
schema: deckhand/DataSchema/v1
|
||||||
|
metadata:
|
||||||
|
name: armada/Chart/v2
|
||||||
|
schema: metadata/Control/v1
|
||||||
|
data:
|
||||||
|
$schema: http://json-schema.org/schema#
|
||||||
|
definitions:
|
||||||
|
labels:
|
||||||
|
type: object
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
hook_action:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
$ref: '#/definitions/labels'
|
||||||
|
required:
|
||||||
|
- type
|
||||||
|
additionalProperties: false
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
release:
|
||||||
|
type: string
|
||||||
|
namespace:
|
||||||
|
type: string
|
||||||
|
values:
|
||||||
|
type: object
|
||||||
|
# TODO: Remove this, and just read dependencies out of `chart` dir as helm
|
||||||
|
# CLI does.
|
||||||
|
dependencies:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
protected:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
continue_processing:
|
||||||
|
type: boolean
|
||||||
|
additionalProperties: false
|
||||||
|
test:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
timeout:
|
||||||
|
type: integer
|
||||||
|
options:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
cleanup:
|
||||||
|
type: boolean
|
||||||
|
additionalProperties: false
|
||||||
|
additionalProperties: false
|
||||||
|
wait:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
timeout:
|
||||||
|
type: integer
|
||||||
|
resources:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
labels:
|
||||||
|
$ref: '#/definitions/labels'
|
||||||
|
min_ready:
|
||||||
|
anyOf:
|
||||||
|
- type: integer
|
||||||
|
- type: string
|
||||||
|
required:
|
||||||
|
- type
|
||||||
|
additionalProperties: false
|
||||||
|
labels:
|
||||||
|
$ref: "#/definitions/labels"
|
||||||
|
# Config for helm's native `--wait` param.
|
||||||
|
native:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
enabled:
|
||||||
|
type: boolean
|
||||||
|
additionalProperties: false
|
||||||
|
additionalProperties: false
|
||||||
|
source:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
type:
|
||||||
|
type: string
|
||||||
|
location:
|
||||||
|
type: string
|
||||||
|
subpath:
|
||||||
|
type: string
|
||||||
|
reference:
|
||||||
|
type: string
|
||||||
|
proxy_server:
|
||||||
|
type: string
|
||||||
|
auth_method:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- location
|
||||||
|
- type
|
||||||
|
delete:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
timeout:
|
||||||
|
type: integer
|
||||||
|
upgrade:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
no_hooks:
|
||||||
|
type: boolean
|
||||||
|
pre:
|
||||||
|
type: object
|
||||||
|
additionalProperties: false
|
||||||
|
properties:
|
||||||
|
delete:
|
||||||
|
$ref: '#/definitions/hook_action'
|
||||||
|
options:
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
force:
|
||||||
|
type: boolean
|
||||||
|
recreate_pods:
|
||||||
|
type: boolean
|
||||||
|
additionalProperties: false
|
||||||
|
additionalProperties: false
|
||||||
|
required:
|
||||||
|
- namespace
|
||||||
|
- release
|
||||||
|
- source
|
||||||
|
additionalProperties: false
|
||||||
|
...
|
|
@ -12,7 +12,7 @@
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
# JSON schema for validating Armada chart groups.
|
# NOTE: Do not modify this schema, it is deprecated.
|
||||||
---
|
---
|
||||||
schema: deckhand/DataSchema/v1
|
schema: deckhand/DataSchema/v1
|
||||||
metadata:
|
metadata:
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# JSON schema for validating Armada chart groups.
|
||||||
|
---
|
||||||
|
schema: deckhand/DataSchema/v1
|
||||||
|
metadata:
|
||||||
|
name: armada/ChartGroup/v2
|
||||||
|
schema: metadata/Control/v1
|
||||||
|
data:
|
||||||
|
$schema: http://json-schema.org/schema#
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
type: string
|
||||||
|
description:
|
||||||
|
type: string
|
||||||
|
sequenced:
|
||||||
|
type: boolean
|
||||||
|
chart_group:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
# TODO: Rename to `charts`?
|
||||||
|
- chart_group
|
||||||
|
additionalProperties: false
|
||||||
|
...
|
|
@ -0,0 +1,34 @@
|
||||||
|
# Copyright 2017 AT&T Intellectual Property. All other rights reserved.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
# NOTE: Do not modify this schema, it is deprecated.
|
||||||
|
---
|
||||||
|
schema: deckhand/DataSchema/v1
|
||||||
|
metadata:
|
||||||
|
name: armada/Manifest/v1
|
||||||
|
schema: metadata/Control/v1
|
||||||
|
data:
|
||||||
|
$schema: http://json-schema.org/schema#
|
||||||
|
properties:
|
||||||
|
release_prefix:
|
||||||
|
type: string
|
||||||
|
chart_groups:
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- chart_groups
|
||||||
|
- release_prefix
|
||||||
|
additionalProperties: false
|
||||||
|
...
|
|
@ -16,7 +16,7 @@
|
||||||
---
|
---
|
||||||
schema: deckhand/DataSchema/v1
|
schema: deckhand/DataSchema/v1
|
||||||
metadata:
|
metadata:
|
||||||
name: armada/Manifest/v1
|
name: armada/Manifest/v2
|
||||||
schema: metadata/Control/v1
|
schema: metadata/Control/v1
|
||||||
data:
|
data:
|
||||||
$schema: http://json-schema.org/schema#
|
$schema: http://json-schema.org/schema#
|
|
@ -169,8 +169,7 @@ class TestReleasesManifestControllerNegativeTest(base.BaseControllerTest):
|
||||||
self.assertIn({
|
self.assertIn({
|
||||||
'message':
|
'message':
|
||||||
('An error occurred while building chart group: '
|
('An error occurred while building chart group: '
|
||||||
'Could not build chart group keystone-infra-services in '
|
'Could not build ChartGroup named "keystone-infra-services".'),
|
||||||
'armada/ChartGroup/v1.'),
|
|
||||||
'error':
|
'error':
|
||||||
True,
|
True,
|
||||||
'kind':
|
'kind':
|
||||||
|
|
|
@ -158,125 +158,153 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase):
|
||||||
armada_obj.pre_flight_ops()
|
armada_obj.pre_flight_ops()
|
||||||
|
|
||||||
expected_config = {
|
expected_config = {
|
||||||
'armada': {
|
'schema': 'armada/Manifest/v1',
|
||||||
'release_prefix':
|
'metadata': {
|
||||||
'armada',
|
'schema': 'metadata/Document/v1',
|
||||||
|
'name': 'example-manifest'
|
||||||
|
},
|
||||||
|
'data': {
|
||||||
|
'release_prefix': 'armada',
|
||||||
'chart_groups': [{
|
'chart_groups': [{
|
||||||
'chart_group': [{
|
'schema': 'armada/ChartGroup/v1',
|
||||||
'chart': {
|
'metadata': {
|
||||||
'dependencies': [],
|
'schema': 'metadata/Document/v1',
|
||||||
'chart_name': 'test_chart_1',
|
'name': 'example-group'
|
||||||
'namespace': 'test',
|
},
|
||||||
'release': 'test_chart_1',
|
'data': {
|
||||||
'source': {
|
'chart_group': [{
|
||||||
'location': ('git://github.com/dummy/armada'),
|
'schema': 'armada/Chart/v1',
|
||||||
'reference': 'master',
|
'metadata': {
|
||||||
'subpath': 'chart_1',
|
'schema': 'metadata/Document/v1',
|
||||||
'type': 'git'
|
'name': 'example-chart-1'
|
||||||
},
|
},
|
||||||
'source_dir': CHART_SOURCES[0],
|
'data': {
|
||||||
'values': {},
|
'dependencies': [],
|
||||||
'wait': {
|
'chart_name': 'test_chart_1',
|
||||||
'timeout': 10,
|
'namespace': 'test',
|
||||||
'native': {
|
'release': 'test_chart_1',
|
||||||
'enabled': False
|
'source': {
|
||||||
}
|
'location':
|
||||||
},
|
'git://github.com/dummy/armada',
|
||||||
'test': {
|
'reference': 'master',
|
||||||
'enabled': True
|
'subpath': 'chart_1',
|
||||||
}
|
'type': 'git'
|
||||||
}
|
},
|
||||||
}, {
|
'source_dir': CHART_SOURCES[0],
|
||||||
'chart': {
|
'values': {},
|
||||||
'dependencies': [],
|
'wait': {
|
||||||
'chart_name': 'test_chart_2',
|
'timeout': 10,
|
||||||
'namespace': 'test',
|
'native': {
|
||||||
'protected': {
|
'enabled': False
|
||||||
'continue_processing': True
|
}
|
||||||
},
|
},
|
||||||
'release': 'test_chart_2',
|
'test': {
|
||||||
'source': {
|
'enabled': True
|
||||||
'location': '/tmp/dummy/armada',
|
|
||||||
'subpath': 'chart_2',
|
|
||||||
'type': 'local'
|
|
||||||
},
|
|
||||||
'source_dir': CHART_SOURCES[1],
|
|
||||||
'values': {},
|
|
||||||
'wait': {
|
|
||||||
'timeout': 10
|
|
||||||
},
|
|
||||||
'upgrade': {
|
|
||||||
'no_hooks': False,
|
|
||||||
'options': {
|
|
||||||
'force': True,
|
|
||||||
'recreate_pods': True
|
|
||||||
}
|
|
||||||
},
|
|
||||||
'test': {
|
|
||||||
'enabled': True,
|
|
||||||
'options': {
|
|
||||||
'cleanup': True
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}, {
|
||||||
}, {
|
'schema': 'armada/Chart/v1',
|
||||||
'chart': {
|
'metadata': {
|
||||||
'dependencies': [],
|
'schema': 'metadata/Document/v1',
|
||||||
'chart_name': 'test_chart_3',
|
'name': 'example-chart-2'
|
||||||
'namespace': 'test',
|
|
||||||
'protected': {
|
|
||||||
'continue_processing': False
|
|
||||||
},
|
},
|
||||||
'release': 'test_chart_3',
|
'data': {
|
||||||
'source': {
|
'dependencies': [],
|
||||||
'location': '/tmp/dummy/armada',
|
'chart_name': 'test_chart_2',
|
||||||
'subpath': 'chart_3',
|
'namespace': 'test',
|
||||||
'type': 'local'
|
'protected': {
|
||||||
},
|
'continue_processing': True
|
||||||
'source_dir': CHART_SOURCES[2],
|
},
|
||||||
'values': {},
|
'release': 'test_chart_2',
|
||||||
'wait': {
|
'source': {
|
||||||
'timeout': 10
|
'location': '/tmp/dummy/armada',
|
||||||
},
|
'subpath': 'chart_2',
|
||||||
'upgrade': {
|
'type': 'local'
|
||||||
'no_hooks': False
|
},
|
||||||
|
'source_dir': CHART_SOURCES[1],
|
||||||
|
'values': {},
|
||||||
|
'wait': {
|
||||||
|
'timeout': 10
|
||||||
|
},
|
||||||
|
'upgrade': {
|
||||||
|
'no_hooks': False,
|
||||||
|
'options': {
|
||||||
|
'force': True,
|
||||||
|
'recreate_pods': True
|
||||||
|
}
|
||||||
|
},
|
||||||
|
'test': {
|
||||||
|
'enabled': True,
|
||||||
|
'options': {
|
||||||
|
'cleanup': True
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}, {
|
||||||
}, {
|
'schema': 'armada/Chart/v1',
|
||||||
'chart': {
|
'metadata': {
|
||||||
'dependencies': [],
|
'schema': 'metadata/Document/v1',
|
||||||
'chart_name': 'test_chart_4',
|
'name': 'example-chart-3'
|
||||||
'namespace': 'test',
|
|
||||||
'release': 'test_chart_4',
|
|
||||||
'source': {
|
|
||||||
'location': '/tmp/dummy/armada',
|
|
||||||
'subpath': 'chart_4',
|
|
||||||
'type': 'local'
|
|
||||||
},
|
},
|
||||||
'source_dir': CHART_SOURCES[3],
|
'data': {
|
||||||
'values': {},
|
'dependencies': [],
|
||||||
'wait': {
|
'chart_name': 'test_chart_3',
|
||||||
'timeout': 10
|
'namespace': 'test',
|
||||||
|
'protected': {
|
||||||
|
'continue_processing': False
|
||||||
|
},
|
||||||
|
'release': 'test_chart_3',
|
||||||
|
'source': {
|
||||||
|
'location': '/tmp/dummy/armada',
|
||||||
|
'subpath': 'chart_3',
|
||||||
|
'type': 'local'
|
||||||
|
},
|
||||||
|
'source_dir': CHART_SOURCES[2],
|
||||||
|
'values': {},
|
||||||
|
'wait': {
|
||||||
|
'timeout': 10
|
||||||
|
},
|
||||||
|
'upgrade': {
|
||||||
|
'no_hooks': False
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
'schema': 'armada/Chart/v1',
|
||||||
|
'metadata': {
|
||||||
|
'schema': 'metadata/Document/v1',
|
||||||
|
'name': 'example-chart-4'
|
||||||
},
|
},
|
||||||
'upgrade': {
|
'data': {
|
||||||
'no_hooks': False
|
'dependencies': [],
|
||||||
},
|
'chart_name': 'test_chart_4',
|
||||||
'test': True
|
'namespace': 'test',
|
||||||
}
|
'release': 'test_chart_4',
|
||||||
}],
|
'source': {
|
||||||
'description':
|
'location': '/tmp/dummy/armada',
|
||||||
'this is a test',
|
'subpath': 'chart_4',
|
||||||
'name':
|
'type': 'local'
|
||||||
'example-group',
|
},
|
||||||
'sequenced':
|
'source_dir': CHART_SOURCES[3],
|
||||||
True
|
'values': {},
|
||||||
|
'wait': {
|
||||||
|
'timeout': 10
|
||||||
|
},
|
||||||
|
'upgrade': {
|
||||||
|
'no_hooks': False
|
||||||
|
},
|
||||||
|
'test': True
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'description': 'this is a test',
|
||||||
|
'sequenced': True
|
||||||
|
}
|
||||||
}]
|
}]
|
||||||
}
|
}
|
||||||
} # yapf: disable
|
} # yapf: disable
|
||||||
|
|
||||||
self.assertTrue(hasattr(armada_obj, 'manifest'))
|
self.assertTrue(hasattr(armada_obj, 'manifest'))
|
||||||
self.assertIsInstance(armada_obj.manifest, dict)
|
self.assertIsInstance(armada_obj.manifest, dict)
|
||||||
self.assertIn('armada', armada_obj.manifest)
|
self.assertIn('data', armada_obj.manifest)
|
||||||
self.assertEqual(expected_config, armada_obj.manifest)
|
self.assertEqual(expected_config, armada_obj.manifest)
|
||||||
|
|
||||||
@mock.patch.object(armada, 'source')
|
@mock.patch.object(armada, 'source')
|
||||||
|
@ -314,9 +342,11 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase):
|
||||||
|
|
||||||
armada_obj.post_flight_ops()
|
armada_obj.post_flight_ops()
|
||||||
|
|
||||||
for group in armada_obj.manifest['armada']['chart_groups']:
|
for group in armada_obj.manifest['data']['chart_groups']:
|
||||||
for counter, chart in enumerate(group.get('chart_group')):
|
for counter, chart in enumerate(
|
||||||
if chart.get('chart').get('source').get('type') == 'git':
|
group.get(const.KEYWORD_DATA).get(const.KEYWORD_CHARTS)):
|
||||||
|
if chart.get(
|
||||||
|
const.KEYWORD_DATA).get('source').get('type') == 'git':
|
||||||
mock_source.source_cleanup.assert_called_with(
|
mock_source.source_cleanup.assert_called_with(
|
||||||
CHART_SOURCES[counter][0])
|
CHART_SOURCES[counter][0])
|
||||||
|
|
||||||
|
@ -348,7 +378,8 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase):
|
||||||
armada_obj = armada.Armada(yaml_documents, m_tiller)
|
armada_obj = armada.Armada(yaml_documents, m_tiller)
|
||||||
armada_obj.chart_deploy.get_diff = mock.Mock()
|
armada_obj.chart_deploy.get_diff = mock.Mock()
|
||||||
|
|
||||||
chart_group = armada_obj.manifest['armada']['chart_groups'][0]
|
cg = armada_obj.manifest['data']['chart_groups'][0]
|
||||||
|
chart_group = cg['data']
|
||||||
charts = chart_group['chart_group']
|
charts = chart_group['chart_group']
|
||||||
cg_test_all_charts = chart_group.get('test_charts')
|
cg_test_all_charts = chart_group.get('test_charts')
|
||||||
|
|
||||||
|
@ -380,9 +411,9 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase):
|
||||||
expected_test_constructor_calls = []
|
expected_test_constructor_calls = []
|
||||||
|
|
||||||
for c in charts:
|
for c in charts:
|
||||||
chart = c['chart']
|
chart = c['data']
|
||||||
release = chart['release']
|
release = chart['release']
|
||||||
prefix = armada_obj.manifest['armada']['release_prefix']
|
prefix = armada_obj.manifest['data']['release_prefix']
|
||||||
release_name = release_prefixer(prefix, release)
|
release_name = release_prefixer(prefix, release)
|
||||||
# Simplified check because the actual code uses logical-or's
|
# Simplified check because the actual code uses logical-or's
|
||||||
# multiple conditions, so this is enough.
|
# multiple conditions, so this is enough.
|
||||||
|
@ -394,8 +425,8 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase):
|
||||||
mock.call(
|
mock.call(
|
||||||
mock_chartbuilder().get_helm_chart(),
|
mock_chartbuilder().get_helm_chart(),
|
||||||
"{}-{}".format(
|
"{}-{}".format(
|
||||||
armada_obj.manifest['armada']
|
armada_obj.manifest['data']['release_prefix'],
|
||||||
['release_prefix'], chart['release']),
|
chart['release']),
|
||||||
chart['namespace'],
|
chart['namespace'],
|
||||||
values=yaml.safe_dump(chart['values']),
|
values=yaml.safe_dump(chart['values']),
|
||||||
wait=native_wait_enabled,
|
wait=native_wait_enabled,
|
||||||
|
@ -420,7 +451,7 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase):
|
||||||
mock.call(
|
mock.call(
|
||||||
mock_chartbuilder().get_helm_chart(),
|
mock_chartbuilder().get_helm_chart(),
|
||||||
"{}-{}".format(
|
"{}-{}".format(
|
||||||
armada_obj.manifest['armada']
|
armada_obj.manifest['data']
|
||||||
['release_prefix'],
|
['release_prefix'],
|
||||||
chart['release']),
|
chart['release']),
|
||||||
chart['namespace'],
|
chart['namespace'],
|
||||||
|
@ -449,7 +480,7 @@ class ArmadaHandlerTestCase(base.ArmadaTestCase):
|
||||||
mock.call(
|
mock.call(
|
||||||
mock_chartbuilder().get_helm_chart(),
|
mock_chartbuilder().get_helm_chart(),
|
||||||
"{}-{}".format(
|
"{}-{}".format(
|
||||||
armada_obj.manifest['armada']
|
armada_obj.manifest['data']
|
||||||
['release_prefix'],
|
['release_prefix'],
|
||||||
chart['release']),
|
chart['release']),
|
||||||
chart['namespace'],
|
chart['namespace'],
|
||||||
|
@ -647,8 +678,8 @@ class ArmadaNegativeHandlerTestCase(base.ArmadaTestCase):
|
||||||
def test_armada_get_manifest_exception(self, mock_source):
|
def test_armada_get_manifest_exception(self, mock_source):
|
||||||
"""Test armada handling with invalid manifest."""
|
"""Test armada handling with invalid manifest."""
|
||||||
yaml_documents = list(yaml.safe_load_all(TEST_YAML))
|
yaml_documents = list(yaml.safe_load_all(TEST_YAML))
|
||||||
error_re = ('Documents must be a list of documents with at least one '
|
error_re = ('.*Documents must include at least one of each of .* and '
|
||||||
'of each of the following schemas: .*')
|
'only one .*')
|
||||||
self.assertRaisesRegexp(ManifestException, error_re, armada.Armada,
|
self.assertRaisesRegexp(ManifestException, error_re, armada.Armada,
|
||||||
yaml_documents[:1], mock.MagicMock())
|
yaml_documents[:1], mock.MagicMock())
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,7 @@ from hapi.chart.metadata_pb2 import Metadata
|
||||||
import mock
|
import mock
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
|
from armada import const
|
||||||
from armada.handlers.chartbuilder import ChartBuilder
|
from armada.handlers.chartbuilder import ChartBuilder
|
||||||
from armada.exceptions import chartbuilder_exceptions
|
from armada.exceptions import chartbuilder_exceptions
|
||||||
|
|
||||||
|
@ -59,7 +60,9 @@ class BaseChartBuilderTestCase(testtools.TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
chart_stream = """
|
chart_stream = """
|
||||||
chart:
|
metadata:
|
||||||
|
name: test
|
||||||
|
data:
|
||||||
chart_name: mariadb
|
chart_name: mariadb
|
||||||
release: mariadb
|
release: mariadb
|
||||||
namespace: openstack
|
namespace: openstack
|
||||||
|
@ -87,7 +90,9 @@ class BaseChartBuilderTestCase(testtools.TestCase):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
dependency_chart_stream = """
|
dependency_chart_stream = """
|
||||||
chart:
|
metadata:
|
||||||
|
name: dep
|
||||||
|
data:
|
||||||
chart_name: keystone
|
chart_name: keystone
|
||||||
release: keystone
|
release: keystone
|
||||||
namespace: undercloud
|
namespace: undercloud
|
||||||
|
@ -120,6 +125,16 @@ class BaseChartBuilderTestCase(testtools.TestCase):
|
||||||
self.addCleanup(shutil.rmtree, subdir)
|
self.addCleanup(shutil.rmtree, subdir)
|
||||||
return subdir
|
return subdir
|
||||||
|
|
||||||
|
def _get_test_chart(self, chart_dir):
|
||||||
|
return {
|
||||||
|
'metadata': {
|
||||||
|
'name': 'test'
|
||||||
|
},
|
||||||
|
const.KEYWORD_DATA: {
|
||||||
|
'source_dir': (chart_dir.path, '')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
|
|
||||||
|
@ -131,8 +146,7 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
||||||
self.chart_yaml)
|
self.chart_yaml)
|
||||||
|
|
||||||
test_chart = {'source_dir': (chart_dir.path, '')}
|
chartbuilder = ChartBuilder(self._get_test_chart(chart_dir))
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
|
||||||
|
|
||||||
# Validate response type is :class:`hapi.chart.metadata_pb2.Metadata`
|
# Validate response type is :class:`hapi.chart.metadata_pb2.Metadata`
|
||||||
resp = chartbuilder.get_metadata()
|
resp = chartbuilder.get_metadata()
|
||||||
|
@ -142,8 +156,7 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
chart_dir = self.useFixture(fixtures.TempDir())
|
chart_dir = self.useFixture(fixtures.TempDir())
|
||||||
self.addCleanup(shutil.rmtree, chart_dir.path)
|
self.addCleanup(shutil.rmtree, chart_dir.path)
|
||||||
|
|
||||||
test_chart = {'source_dir': (chart_dir.path, '')}
|
chartbuilder = ChartBuilder(self._get_test_chart(chart_dir))
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
|
||||||
|
|
||||||
self.assertRaises(chartbuilder_exceptions.MetadataLoadException,
|
self.assertRaises(chartbuilder_exceptions.MetadataLoadException,
|
||||||
chartbuilder.get_metadata)
|
chartbuilder.get_metadata)
|
||||||
|
@ -168,8 +181,7 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
for filename in ['template%d' % x for x in range(3)]:
|
for filename in ['template%d' % x for x in range(3)]:
|
||||||
self._write_temporary_file_contents(templates_subdir, filename, "")
|
self._write_temporary_file_contents(templates_subdir, filename, "")
|
||||||
|
|
||||||
test_chart = {'source_dir': (chart_dir.path, '')}
|
chartbuilder = ChartBuilder(self._get_test_chart(chart_dir))
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
|
||||||
|
|
||||||
expected_files = (
|
expected_files = (
|
||||||
'[type_url: "%s"\n, type_url: "%s"\n]' % ('./bar', './foo'))
|
'[type_url: "%s"\n, type_url: "%s"\n]' % ('./bar', './foo'))
|
||||||
|
@ -185,8 +197,7 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self._write_temporary_file_contents(
|
self._write_temporary_file_contents(
|
||||||
chart_dir.path, filename, "DIRC^@^@^@^B^@^@^@×Z®<86>F.1")
|
chart_dir.path, filename, "DIRC^@^@^@^B^@^@^@×Z®<86>F.1")
|
||||||
|
|
||||||
test_chart = {'source_dir': (chart_dir.path, '')}
|
chartbuilder = ChartBuilder(self._get_test_chart(chart_dir))
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
|
||||||
chartbuilder.get_files()
|
chartbuilder.get_files()
|
||||||
|
|
||||||
def test_get_basic_helm_chart(self):
|
def test_get_basic_helm_chart(self):
|
||||||
|
@ -197,8 +208,8 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self.addCleanup(shutil.rmtree, chart_dir.path)
|
self.addCleanup(shutil.rmtree, chart_dir.path)
|
||||||
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
||||||
self.chart_yaml)
|
self.chart_yaml)
|
||||||
ch = yaml.safe_load(self.chart_stream)['chart']
|
ch = yaml.safe_load(self.chart_stream)
|
||||||
ch['source_dir'] = (chart_dir.path, '')
|
ch['data']['source_dir'] = (chart_dir.path, '')
|
||||||
|
|
||||||
test_chart = ch
|
test_chart = ch
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
chartbuilder = ChartBuilder(test_chart)
|
||||||
|
@ -228,8 +239,8 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self._write_temporary_file_contents(chart_dir.path, 'values.yaml',
|
self._write_temporary_file_contents(chart_dir.path, 'values.yaml',
|
||||||
self.chart_value)
|
self.chart_value)
|
||||||
|
|
||||||
ch = yaml.safe_load(self.chart_stream)['chart']
|
ch = yaml.safe_load(self.chart_stream)
|
||||||
ch['source_dir'] = (chart_dir.path, '')
|
ch['data']['source_dir'] = (chart_dir.path, '')
|
||||||
|
|
||||||
test_chart = ch
|
test_chart = ch
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
chartbuilder = ChartBuilder(test_chart)
|
||||||
|
@ -257,8 +268,8 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
'nested')
|
'nested')
|
||||||
self._write_temporary_file_contents(nested_dir, 'nested0', "random")
|
self._write_temporary_file_contents(nested_dir, 'nested0', "random")
|
||||||
|
|
||||||
ch = yaml.safe_load(self.chart_stream)['chart']
|
ch = yaml.safe_load(self.chart_stream)
|
||||||
ch['source_dir'] = (chart_dir.path, '')
|
ch['data']['source_dir'] = (chart_dir.path, '')
|
||||||
|
|
||||||
test_chart = ch
|
test_chart = ch
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
chartbuilder = ChartBuilder(test_chart)
|
||||||
|
@ -313,8 +324,8 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
# Files to **include** within charts/ subdirectory.
|
# Files to **include** within charts/ subdirectory.
|
||||||
self._write_temporary_file_contents(charts_subdir, '.prov', "xyzzy")
|
self._write_temporary_file_contents(charts_subdir, '.prov', "xyzzy")
|
||||||
|
|
||||||
ch = yaml.safe_load(self.chart_stream)['chart']
|
ch = yaml.safe_load(self.chart_stream)
|
||||||
ch['source_dir'] = (chart_dir.path, '')
|
ch['data']['source_dir'] = (chart_dir.path, '')
|
||||||
|
|
||||||
test_chart = ch
|
test_chart = ch
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
chartbuilder = ChartBuilder(test_chart)
|
||||||
|
@ -340,8 +351,8 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self.addCleanup(shutil.rmtree, chart_dir.path)
|
self.addCleanup(shutil.rmtree, chart_dir.path)
|
||||||
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
||||||
self.chart_yaml)
|
self.chart_yaml)
|
||||||
ch = yaml.safe_load(self.chart_stream)['chart']
|
ch = yaml.safe_load(self.chart_stream)
|
||||||
ch['source_dir'] = (chart_dir.path, '')
|
ch['data']['source_dir'] = (chart_dir.path, '')
|
||||||
|
|
||||||
# Dependency chart directory and files.
|
# Dependency chart directory and files.
|
||||||
dep_chart_dir = self.useFixture(fixtures.TempDir())
|
dep_chart_dir = self.useFixture(fixtures.TempDir())
|
||||||
|
@ -349,11 +360,11 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self._write_temporary_file_contents(dep_chart_dir.path, 'Chart.yaml',
|
self._write_temporary_file_contents(dep_chart_dir.path, 'Chart.yaml',
|
||||||
self.dependency_chart_yaml)
|
self.dependency_chart_yaml)
|
||||||
dep_ch = yaml.safe_load(self.dependency_chart_stream)
|
dep_ch = yaml.safe_load(self.dependency_chart_stream)
|
||||||
dep_ch['chart']['source_dir'] = (dep_chart_dir.path, '')
|
dep_ch['data']['source_dir'] = (dep_chart_dir.path, '')
|
||||||
|
|
||||||
main_chart = ch
|
main_chart = ch
|
||||||
dependency_chart = dep_ch
|
dependency_chart = dep_ch
|
||||||
main_chart['dependencies'] = [dependency_chart]
|
main_chart['data']['dependencies'] = [dependency_chart]
|
||||||
|
|
||||||
chartbuilder = ChartBuilder(main_chart)
|
chartbuilder = ChartBuilder(main_chart)
|
||||||
helm_chart = chartbuilder.get_helm_chart()
|
helm_chart = chartbuilder.get_helm_chart()
|
||||||
|
@ -409,8 +420,8 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self.addCleanup(shutil.rmtree, chart_dir.path)
|
self.addCleanup(shutil.rmtree, chart_dir.path)
|
||||||
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
self._write_temporary_file_contents(chart_dir.path, 'Chart.yaml',
|
||||||
self.chart_yaml)
|
self.chart_yaml)
|
||||||
ch = yaml.safe_load(self.chart_stream)['chart']
|
ch = yaml.safe_load(self.chart_stream)
|
||||||
ch['source_dir'] = (chart_dir.path, '')
|
ch['data']['source_dir'] = (chart_dir.path, '')
|
||||||
|
|
||||||
test_chart = ch
|
test_chart = ch
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
chartbuilder = ChartBuilder(test_chart)
|
||||||
|
@ -424,10 +435,10 @@ class ChartBuilderTestCase(BaseChartBuilderTestCase):
|
||||||
self._write_temporary_file_contents(dep_chart_dir.path, 'Chart.yaml',
|
self._write_temporary_file_contents(dep_chart_dir.path, 'Chart.yaml',
|
||||||
self.dependency_chart_yaml)
|
self.dependency_chart_yaml)
|
||||||
dep_ch = yaml.safe_load(self.dependency_chart_stream)
|
dep_ch = yaml.safe_load(self.dependency_chart_stream)
|
||||||
dep_ch['chart']['source_dir'] = (dep_chart_dir.path, '')
|
dep_ch['data']['source_dir'] = (dep_chart_dir.path, '')
|
||||||
|
|
||||||
dependency_chart = dep_ch
|
dependency_chart = dep_ch
|
||||||
test_chart['dependencies'] = [dependency_chart]
|
test_chart['data']['dependencies'] = [dependency_chart]
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
chartbuilder = ChartBuilder(test_chart)
|
||||||
|
|
||||||
re = inspect.cleandoc("""
|
re = inspect.cleandoc("""
|
||||||
|
@ -457,8 +468,7 @@ class ChartBuilderNegativeTestCase(BaseChartBuilderTestCase):
|
||||||
self._write_temporary_file_contents(
|
self._write_temporary_file_contents(
|
||||||
chart_dir.path, filename, "DIRC^@^@^@^B^@^@^@×Z®<86>F.1")
|
chart_dir.path, filename, "DIRC^@^@^@^B^@^@^@×Z®<86>F.1")
|
||||||
|
|
||||||
test_chart = {'source_dir': (chart_dir.path, '')}
|
chartbuilder = ChartBuilder(self._get_test_chart(chart_dir))
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
|
||||||
|
|
||||||
# Confirm it failed for both encodings.
|
# Confirm it failed for both encodings.
|
||||||
error_re = (r'.*A str exception occurred while trying to read file:'
|
error_re = (r'.*A str exception occurred while trying to read file:'
|
||||||
|
@ -477,8 +487,7 @@ class ChartBuilderNegativeTestCase(BaseChartBuilderTestCase):
|
||||||
self._write_temporary_file_contents(
|
self._write_temporary_file_contents(
|
||||||
chart_dir.path, filename, "DIRC^@^@^@^B^@^@^@×Z®<86>F.1")
|
chart_dir.path, filename, "DIRC^@^@^@^B^@^@^@×Z®<86>F.1")
|
||||||
|
|
||||||
test_chart = {'source_dir': (chart_dir.path, '')}
|
chartbuilder = ChartBuilder(self._get_test_chart(chart_dir))
|
||||||
chartbuilder = ChartBuilder(test_chart)
|
|
||||||
|
|
||||||
side_effects = [self.exc_to_raise, "", ""]
|
side_effects = [self.exc_to_raise, "", ""]
|
||||||
with mock.patch("builtins.open", mock.mock_open(read_data="")) \
|
with mock.patch("builtins.open", mock.mock_open(read_data="")) \
|
||||||
|
|
|
@ -18,9 +18,9 @@ import yaml
|
||||||
|
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from armada import const
|
|
||||||
from armada import exceptions
|
from armada import exceptions
|
||||||
from armada.handlers import manifest
|
from armada.handlers import manifest
|
||||||
|
from armada.handlers import schema
|
||||||
from armada.utils import validate
|
from armada.utils import validate
|
||||||
|
|
||||||
|
|
||||||
|
@ -111,7 +111,7 @@ class ManifestTestCase(testtools.TestCase):
|
||||||
self.documents, target_manifest='armada-manifest')
|
self.documents, target_manifest='armada-manifest')
|
||||||
obtained_manifest = armada_manifest.get_manifest()
|
obtained_manifest = armada_manifest.get_manifest()
|
||||||
self.assertIsInstance(obtained_manifest, dict)
|
self.assertIsInstance(obtained_manifest, dict)
|
||||||
self.assertEqual(obtained_manifest['armada'],
|
self.assertEqual(obtained_manifest['data'],
|
||||||
armada_manifest.manifest['data'])
|
armada_manifest.manifest['data'])
|
||||||
|
|
||||||
def test_find_documents(self):
|
def test_find_documents(self):
|
||||||
|
@ -194,19 +194,15 @@ class ManifestTestCase(testtools.TestCase):
|
||||||
# the first chart group in the Armada manifest
|
# the first chart group in the Armada manifest
|
||||||
keystone_infra_services_chart_group = armada_manifest. \
|
keystone_infra_services_chart_group = armada_manifest. \
|
||||||
find_chart_group_document('keystone-infra-services')
|
find_chart_group_document('keystone-infra-services')
|
||||||
keystone_infra_services_chart_group_data = \
|
|
||||||
keystone_infra_services_chart_group.get('data')
|
|
||||||
|
|
||||||
self.assertEqual(keystone_infra_services_chart_group_data,
|
self.assertEqual(keystone_infra_services_chart_group,
|
||||||
built_armada_manifest['data']['chart_groups'][0])
|
built_armada_manifest['data']['chart_groups'][0])
|
||||||
|
|
||||||
# the first chart group in the Armada manifest
|
# the first chart group in the Armada manifest
|
||||||
openstack_keystone_chart_group = armada_manifest. \
|
openstack_keystone_chart_group = armada_manifest. \
|
||||||
find_chart_group_document('openstack-keystone')
|
find_chart_group_document('openstack-keystone')
|
||||||
openstack_keystone_chart_group_data = \
|
|
||||||
openstack_keystone_chart_group.get('data')
|
|
||||||
|
|
||||||
self.assertEqual(openstack_keystone_chart_group_data,
|
self.assertEqual(openstack_keystone_chart_group,
|
||||||
built_armada_manifest['data']['chart_groups'][1])
|
built_armada_manifest['data']['chart_groups'][1])
|
||||||
|
|
||||||
def test_verify_build_chart_group_deps(self):
|
def test_verify_build_chart_group_deps(self):
|
||||||
|
@ -218,7 +214,7 @@ class ManifestTestCase(testtools.TestCase):
|
||||||
build_chart_group(chart_group)
|
build_chart_group(chart_group)
|
||||||
openstack_keystone_chart_group_deps_dep_added = \
|
openstack_keystone_chart_group_deps_dep_added = \
|
||||||
openstack_keystone_chart_group_deps[
|
openstack_keystone_chart_group_deps[
|
||||||
'data']['chart_group'][0]['chart']['dependencies']
|
'data']['chart_group'][0]['data']['dependencies']
|
||||||
|
|
||||||
# keystone chart dependencies
|
# keystone chart dependencies
|
||||||
keystone_chart = armada_manifest.find_chart_document('keystone')
|
keystone_chart = armada_manifest.find_chart_document('keystone')
|
||||||
|
@ -237,7 +233,7 @@ class ManifestTestCase(testtools.TestCase):
|
||||||
build_chart_group(chart_group)
|
build_chart_group(chart_group)
|
||||||
keystone_infra_services_dep_added = \
|
keystone_infra_services_dep_added = \
|
||||||
openstack_keystone_chart_group_deps[
|
openstack_keystone_chart_group_deps[
|
||||||
'data']['chart_group'][0]['chart']['dependencies']
|
'data']['chart_group'][0]['data']['dependencies']
|
||||||
|
|
||||||
# building mariadb chart dependencies
|
# building mariadb chart dependencies
|
||||||
mariadb_chart = armada_manifest.find_chart_document('mariadb')
|
mariadb_chart = armada_manifest.find_chart_document('mariadb')
|
||||||
|
@ -274,9 +270,7 @@ class ManifestTestCase(testtools.TestCase):
|
||||||
|
|
||||||
# helm-toolkit dependency, the basis for comparison of d
|
# helm-toolkit dependency, the basis for comparison of d
|
||||||
# ependencies in other charts
|
# ependencies in other charts
|
||||||
expected_helm_toolkit_dependency = {
|
expected_helm_toolkit_dependency = helm_toolkit_chart
|
||||||
'chart': helm_toolkit_chart.get('data')
|
|
||||||
}
|
|
||||||
|
|
||||||
# keystone chart dependencies
|
# keystone chart dependencies
|
||||||
keystone_chart = armada_manifest.find_chart_document('keystone')
|
keystone_chart = armada_manifest.find_chart_document('keystone')
|
||||||
|
@ -366,42 +360,39 @@ class ManifestNegativeTestCase(testtools.TestCase):
|
||||||
documents,
|
documents,
|
||||||
target_manifest='armada-manifest')
|
target_manifest='armada-manifest')
|
||||||
|
|
||||||
|
def _assert_missing_documents_raises(self, documents):
|
||||||
|
error_re = ('.*Documents must include at least one of each of .* and '
|
||||||
|
'only one .*')
|
||||||
|
self.assertRaisesRegexp(exceptions.ManifestException, error_re,
|
||||||
|
manifest.Manifest, documents)
|
||||||
|
|
||||||
def test_get_documents_missing_manifest(self):
|
def test_get_documents_missing_manifest(self):
|
||||||
# Validates exceptions.ManifestException is thrown if no manifest is
|
# Validates exceptions.ManifestException is thrown if no manifest is
|
||||||
# found. Manifest is last document in sample YAML.
|
# found. Manifest is last document in sample YAML.
|
||||||
error_re = ('Documents must be a list of documents with at least one '
|
self._assert_missing_documents_raises(self.documents[:-1])
|
||||||
'of each of the following schemas: .*')
|
|
||||||
self.assertRaisesRegexp(exceptions.ManifestException, error_re,
|
|
||||||
manifest.Manifest, self.documents[:-1])
|
|
||||||
|
|
||||||
def test_get_documents_missing_charts(self):
|
def test_get_documents_missing_charts(self):
|
||||||
# Validates exceptions.ManifestException is thrown if no chart is
|
# Validates exceptions.ManifestException is thrown if no chart is
|
||||||
# found. Charts are first 5 documents in sample YAML.
|
# found. Charts are first 5 documents in sample YAML.
|
||||||
error_re = ('Documents must be a list of documents with at least one '
|
self._assert_missing_documents_raises(self.documents[5:])
|
||||||
'of each of the following schemas: .*')
|
|
||||||
self.assertRaisesRegexp(exceptions.ManifestException, error_re,
|
|
||||||
manifest.Manifest, self.documents[5:])
|
|
||||||
|
|
||||||
def test_get_documents_missing_chart_groups(self):
|
def test_get_documents_missing_chart_groups(self):
|
||||||
# Validates exceptions.ManifestException is thrown if no chart is
|
# Validates exceptions.ManifestException is thrown if no chart is
|
||||||
# found. ChartGroups are 5-6 documents in sample YAML.
|
# found. ChartGroups are 5-6 documents in sample YAML.
|
||||||
documents = self.documents[:4] + [self.documents[-1]]
|
documents = self.documents[:4] + [self.documents[-1]]
|
||||||
error_re = ('Documents must be a list of documents with at least one '
|
self._assert_missing_documents_raises(documents)
|
||||||
'of each of the following schemas: .*')
|
|
||||||
self.assertRaisesRegexp(exceptions.ManifestException, error_re,
|
|
||||||
manifest.Manifest, documents)
|
|
||||||
|
|
||||||
def test_find_chart_document_negative(self):
|
def test_find_chart_document_negative(self):
|
||||||
armada_manifest = manifest.Manifest(self.documents)
|
armada_manifest = manifest.Manifest(self.documents)
|
||||||
error_re = r'Could not build %s named "%s"' % (const.DOCUMENT_CHART,
|
error_re = r'.*Could not find %s named "%s"' % (schema.TYPE_CHART,
|
||||||
'invalid')
|
'invalid')
|
||||||
self.assertRaisesRegexp(exceptions.BuildChartException, error_re,
|
self.assertRaisesRegexp(exceptions.BuildChartException, error_re,
|
||||||
armada_manifest.find_chart_document, 'invalid')
|
armada_manifest.find_chart_document, 'invalid')
|
||||||
|
|
||||||
def test_find_group_document_negative(self):
|
def test_find_group_document_negative(self):
|
||||||
armada_manifest = manifest.Manifest(self.documents)
|
armada_manifest = manifest.Manifest(self.documents)
|
||||||
error_re = r'Could not build %s named "%s"' % (const.DOCUMENT_GROUP,
|
error_re = r'.*Could not find %s named "%s"' % (schema.TYPE_CHARTGROUP,
|
||||||
'invalid')
|
'invalid')
|
||||||
self.assertRaisesRegexp(exceptions.BuildChartGroupException, error_re,
|
self.assertRaisesRegexp(exceptions.BuildChartGroupException, error_re,
|
||||||
armada_manifest.find_chart_group_document,
|
armada_manifest.find_chart_group_document,
|
||||||
'invalid')
|
'invalid')
|
||||||
|
|
|
@ -20,8 +20,8 @@ import yaml
|
||||||
import testtools
|
import testtools
|
||||||
|
|
||||||
from armada.handlers.override import Override
|
from armada.handlers.override import Override
|
||||||
|
from armada.handlers import schema
|
||||||
from armada.exceptions import override_exceptions
|
from armada.exceptions import override_exceptions
|
||||||
from armada import const
|
|
||||||
|
|
||||||
|
|
||||||
class OverrideTestCase(testtools.TestCase):
|
class OverrideTestCase(testtools.TestCase):
|
||||||
|
@ -117,13 +117,13 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
documents = list(yaml.safe_load_all(f.read()))
|
documents = list(yaml.safe_load_all(f.read()))
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
test_group = ovr.find_document_type('chart_group')
|
test_group = ovr.find_document_type('chart_group')
|
||||||
self.assertEqual(test_group, const.DOCUMENT_GROUP)
|
self.assertEqual(test_group, schema.TYPE_CHARTGROUP)
|
||||||
|
|
||||||
test_chart = ovr.find_document_type('chart')
|
test_chart = ovr.find_document_type('chart')
|
||||||
self.assertEqual(test_chart, const.DOCUMENT_CHART)
|
self.assertEqual(test_chart, schema.TYPE_CHART)
|
||||||
|
|
||||||
test_manifest = ovr.find_document_type('manifest')
|
test_manifest = ovr.find_document_type('manifest')
|
||||||
self.assertEqual(test_manifest, const.DOCUMENT_MANIFEST)
|
self.assertEqual(test_manifest, schema.TYPE_MANIFEST)
|
||||||
|
|
||||||
def test_update_chart_document_valid(self):
|
def test_update_chart_document_valid(self):
|
||||||
with open(self.base_manifest) as f:
|
with open(self.base_manifest) as f:
|
||||||
|
@ -138,7 +138,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
|
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
# update with document values with the modified ones
|
# update with document values with the modified ones
|
||||||
ovr.update_chart_document(documents_modified[0])
|
ovr.update_document(documents_modified[0])
|
||||||
|
|
||||||
# after the update, both documents are equal
|
# after the update, both documents are equal
|
||||||
self.assertEqual(ovr.documents[0]['data']['chart_name'],
|
self.assertEqual(ovr.documents[0]['data']['chart_name'],
|
||||||
|
@ -148,7 +148,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
# Case 2: Checking if dictionaries get updated
|
# Case 2: Checking if dictionaries get updated
|
||||||
documents_modified[0]['data']['values'] = {'foo': 'bar'}
|
documents_modified[0]['data']['values'] = {'foo': 'bar'}
|
||||||
|
|
||||||
ovr.update_chart_document(documents_modified[0])
|
ovr.update_document(documents_modified[0])
|
||||||
|
|
||||||
# after the update, both documents are equal
|
# after the update, both documents are equal
|
||||||
self.assertEqual(ovr.documents[0]['data']['values'],
|
self.assertEqual(ovr.documents[0]['data']['values'],
|
||||||
|
@ -158,7 +158,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
# Case 3: Checking if lists get updated
|
# Case 3: Checking if lists get updated
|
||||||
documents_modified[0]['data']['dependencies'] = ['foo', 'bar']
|
documents_modified[0]['data']['dependencies'] = ['foo', 'bar']
|
||||||
|
|
||||||
ovr.update_chart_document(documents_modified[0])
|
ovr.update_document(documents_modified[0])
|
||||||
|
|
||||||
# after the update, both documents are equal
|
# after the update, both documents are equal
|
||||||
self.assertEqual(['foo', 'bar'],
|
self.assertEqual(['foo', 'bar'],
|
||||||
|
@ -179,7 +179,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
|
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
# update with document values with the modified ones
|
# update with document values with the modified ones
|
||||||
ovr.update_chart_document(documents_modified[0])
|
ovr.update_document(documents_modified[0])
|
||||||
|
|
||||||
self.assertIn('chart_name', ovr.documents[0]['data'])
|
self.assertIn('chart_name', ovr.documents[0]['data'])
|
||||||
self.assertNotEqual(ovr.documents[0], documents_modified[0])
|
self.assertNotEqual(ovr.documents[0], documents_modified[0])
|
||||||
|
@ -195,7 +195,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
|
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
# update with document values with the modified ones
|
# update with document values with the modified ones
|
||||||
ovr.update_chart_group_document(documents_modified[1])
|
ovr.update_document(documents_modified[1])
|
||||||
|
|
||||||
# after the update, both documents are equal
|
# after the update, both documents are equal
|
||||||
self.assertEqual(ovr.documents[1]['data']['sequenced'],
|
self.assertEqual(ovr.documents[1]['data']['sequenced'],
|
||||||
|
@ -214,7 +214,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
|
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
# update with document values with the modified ones
|
# update with document values with the modified ones
|
||||||
ovr.update_chart_group_document(documents_modified[1])
|
ovr.update_document(documents_modified[1])
|
||||||
|
|
||||||
self.assertIn('sequenced', ovr.documents[1]['data'])
|
self.assertIn('sequenced', ovr.documents[1]['data'])
|
||||||
self.assertNotEqual(ovr.documents[1], documents_modified[1])
|
self.assertNotEqual(ovr.documents[1], documents_modified[1])
|
||||||
|
@ -230,7 +230,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
|
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
# update with document values with the modified ones
|
# update with document values with the modified ones
|
||||||
ovr.update_armada_manifest(documents_modified[2])
|
ovr.update_document(documents_modified[2])
|
||||||
|
|
||||||
# after the update, both documents are equal
|
# after the update, both documents are equal
|
||||||
self.assertEqual(ovr.documents[2]['data']['release_prefix'],
|
self.assertEqual(ovr.documents[2]['data']['release_prefix'],
|
||||||
|
@ -249,7 +249,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
|
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
# update with document values from base_manifest
|
# update with document values from base_manifest
|
||||||
ovr.update_armada_manifest(documents_modified[2])
|
ovr.update_document(documents_modified[2])
|
||||||
|
|
||||||
self.assertIn('release_prefix', ovr.documents[2]['data'])
|
self.assertIn('release_prefix', ovr.documents[2]['data'])
|
||||||
self.assertNotEqual(ovr.documents[2], documents_modified[2])
|
self.assertNotEqual(ovr.documents[2], documents_modified[2])
|
||||||
|
@ -265,7 +265,7 @@ class OverrideTestCase(testtools.TestCase):
|
||||||
documents = list(yaml.safe_load_all(f.read()))
|
documents = list(yaml.safe_load_all(f.read()))
|
||||||
doc_path = ['chart', 'blog-1']
|
doc_path = ['chart', 'blog-1']
|
||||||
ovr = Override(documents)
|
ovr = Override(documents)
|
||||||
ovr.update_document(merging_values)
|
ovr.update_documents(merging_values)
|
||||||
ovr_doc = ovr.find_manifest_document(doc_path)
|
ovr_doc = ovr.find_manifest_document(doc_path)
|
||||||
expect_doc = list(yaml.load_all(e.read()))[0]
|
expect_doc = list(yaml.load_all(e.read()))[0]
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
# Copyright 2019 The Armada Authors.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
# you may not use this file except in compliance with the License.
|
||||||
|
# You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
# See the License for the specific language governing permissions and
|
||||||
|
# limitations under the License.
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from armada.utils import schema
|
||||||
|
|
||||||
|
|
||||||
|
class SchemaTestCase(unittest.TestCase):
|
||||||
|
|
||||||
|
def test_validate_load_schemas(self):
|
||||||
|
expected_schemas = [
|
||||||
|
'armada/Chart/v1', 'armada/ChartGroup/v1', 'armada/Manifest/v1'
|
||||||
|
'armada/Chart/v2', 'armada/ChartGroup/v2', 'armada/Manifest/v2'
|
||||||
|
]
|
||||||
|
for expected_schema in expected_schemas:
|
||||||
|
self.assertIn(expected_schema, schema._SCHEMAS)
|
||||||
|
|
||||||
|
def test_validate_load_duplicate_schemas_expect_runtime_error(self):
|
||||||
|
"""Validate that calling ``_load_schemas`` results in a
|
||||||
|
``RuntimeError`` being thrown, because the call is made during module
|
||||||
|
import, and importing the schemas again in manually results in
|
||||||
|
duplicates.
|
||||||
|
"""
|
||||||
|
with self.assertRaisesRegexp(RuntimeError,
|
||||||
|
'Duplicate schema specified for: .*'):
|
||||||
|
schema._load_schemas()
|
|
@ -111,13 +111,6 @@ class ValidateOwnExamplesTestCase(BaseValidateTest):
|
||||||
|
|
||||||
class ValidateTestCase(BaseValidateTest):
|
class ValidateTestCase(BaseValidateTest):
|
||||||
|
|
||||||
def test_validate_load_schemas(self):
|
|
||||||
expected_schemas = [
|
|
||||||
'armada/Chart/v1', 'armada/ChartGroup/v1', 'armada/Manifest/v1'
|
|
||||||
]
|
|
||||||
for expected_schema in expected_schemas:
|
|
||||||
self.assertIn(expected_schema, validate.SCHEMAS)
|
|
||||||
|
|
||||||
def test_validate_armada_yaml_passes(self):
|
def test_validate_armada_yaml_passes(self):
|
||||||
template = '{}/resources/valid_armada_document.yaml'.format(
|
template = '{}/resources/valid_armada_document.yaml'.format(
|
||||||
self.basepath)
|
self.basepath)
|
||||||
|
@ -223,16 +216,6 @@ data:
|
||||||
|
|
||||||
class ValidateNegativeTestCase(BaseValidateTest):
|
class ValidateNegativeTestCase(BaseValidateTest):
|
||||||
|
|
||||||
def test_validate_load_duplicate_schemas_expect_runtime_error(self):
|
|
||||||
"""Validate that calling ``validate._load_schemas`` results in a
|
|
||||||
``RuntimeError`` being thrown, because the call is made during module
|
|
||||||
import, and importing the schemas again in manually results in
|
|
||||||
duplicates.
|
|
||||||
"""
|
|
||||||
with self.assertRaisesRegexp(RuntimeError,
|
|
||||||
'Duplicate schema specified for: .*'):
|
|
||||||
validate._load_schemas()
|
|
||||||
|
|
||||||
def test_validate_no_dictionary_expect_type_error(self):
|
def test_validate_no_dictionary_expect_type_error(self):
|
||||||
expected_error = 'The provided input "invalid" must be a dictionary.'
|
expected_error = 'The provided input "invalid" must be a dictionary.'
|
||||||
self.assertRaisesRegexp(TypeError, expected_error,
|
self.assertRaisesRegexp(TypeError, expected_error,
|
||||||
|
|
|
@ -13,44 +13,18 @@
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
|
||||||
import jsonschema
|
import jsonschema
|
||||||
import os
|
|
||||||
import pkg_resources
|
|
||||||
import requests
|
import requests
|
||||||
import traceback
|
import traceback
|
||||||
import yaml
|
|
||||||
|
|
||||||
from oslo_log import log as logging
|
from oslo_log import log as logging
|
||||||
|
|
||||||
from armada.const import KEYWORD_GROUPS, KEYWORD_CHARTS, KEYWORD_RELEASE
|
from armada import const
|
||||||
|
from armada.handlers import schema as sch
|
||||||
from armada.handlers.manifest import Manifest
|
from armada.handlers.manifest import Manifest
|
||||||
from armada.exceptions.manifest_exceptions import ManifestException
|
from armada.exceptions.manifest_exceptions import ManifestException
|
||||||
from armada.utils.validation_message import ValidationMessage
|
from armada.utils.validation_message import ValidationMessage
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
# Creates a mapping between ``metadata.name``: ``data`` where the
|
|
||||||
# ``metadata.name`` is the ``schema`` of a manifest and the ``data`` is the
|
|
||||||
# JSON schema to be used to validate the manifest in question.
|
|
||||||
SCHEMAS = {}
|
|
||||||
|
|
||||||
|
|
||||||
def _get_schema_dir():
|
|
||||||
return pkg_resources.resource_filename('armada', 'schemas')
|
|
||||||
|
|
||||||
|
|
||||||
def _load_schemas():
|
|
||||||
"""Populates ``SCHEMAS`` with the schemas defined in package
|
|
||||||
``armada.schemas``.
|
|
||||||
|
|
||||||
"""
|
|
||||||
schema_dir = _get_schema_dir()
|
|
||||||
for schema_file in os.listdir(schema_dir):
|
|
||||||
with open(os.path.join(schema_dir, schema_file)) as f:
|
|
||||||
for schema in yaml.safe_load_all(f):
|
|
||||||
name = schema['metadata']['name']
|
|
||||||
if name in SCHEMAS:
|
|
||||||
raise RuntimeError(
|
|
||||||
'Duplicate schema specified for: %s.' % name)
|
|
||||||
SCHEMAS[name] = schema['data']
|
|
||||||
|
|
||||||
|
|
||||||
def _validate_armada_manifest(manifest):
|
def _validate_armada_manifest(manifest):
|
||||||
|
@ -71,7 +45,7 @@ def _validate_armada_manifest(manifest):
|
||||||
details = []
|
details = []
|
||||||
|
|
||||||
try:
|
try:
|
||||||
armada_object = manifest.get_manifest().get('armada')
|
manifest.get_manifest().get(const.KEYWORD_DATA)
|
||||||
except ManifestException as me:
|
except ManifestException as me:
|
||||||
vmsg = ValidationMessage(
|
vmsg = ValidationMessage(
|
||||||
message=str(me), error=True, name='ARM001', level='Error')
|
message=str(me), error=True, name='ARM001', level='Error')
|
||||||
|
@ -80,27 +54,6 @@ def _validate_armada_manifest(manifest):
|
||||||
details.append(vmsg.get_output())
|
details.append(vmsg.get_output())
|
||||||
return False, details
|
return False, details
|
||||||
|
|
||||||
groups = armada_object.get(KEYWORD_GROUPS)
|
|
||||||
|
|
||||||
if not isinstance(groups, list):
|
|
||||||
message = '{} entry is of wrong type: {} (expected: {})'.format(
|
|
||||||
KEYWORD_GROUPS, type(groups), 'list')
|
|
||||||
vmsg = ValidationMessage(
|
|
||||||
message=message, error=True, name='ARM101', level='Error')
|
|
||||||
LOG.info('ValidationMessage: %s', vmsg.get_output_json())
|
|
||||||
details.append(vmsg.get_output())
|
|
||||||
|
|
||||||
for group in groups:
|
|
||||||
for chart in group.get(KEYWORD_CHARTS):
|
|
||||||
chart_obj = chart.get('chart')
|
|
||||||
if KEYWORD_RELEASE not in chart_obj:
|
|
||||||
message = 'Could not find {} keyword in {}'.format(
|
|
||||||
KEYWORD_RELEASE, chart_obj.get('release'))
|
|
||||||
vmsg = ValidationMessage(
|
|
||||||
message=message, error=True, name='ARM102', level='Error')
|
|
||||||
LOG.info('ValidationMessage: %s', vmsg.get_output_json())
|
|
||||||
details.append(vmsg.get_output())
|
|
||||||
|
|
||||||
if len([x for x in details if x.get('error', False)]) > 0:
|
if len([x for x in details if x.get('error', False)]) > 0:
|
||||||
return False, details
|
return False, details
|
||||||
|
|
||||||
|
@ -117,13 +70,16 @@ def validate_armada_manifests(documents):
|
||||||
all_valid = True
|
all_valid = True
|
||||||
|
|
||||||
for document in documents:
|
for document in documents:
|
||||||
if document.get('schema', '') == 'armada/Manifest/v1':
|
doc_schema = document.get('schema')
|
||||||
target = document.get('metadata').get('name')
|
if doc_schema:
|
||||||
# TODO(MarshM) explore: why does this pass 'documents'?
|
schema_info = sch.get_schema_info(doc_schema)
|
||||||
manifest = Manifest(documents, target_manifest=target)
|
if schema_info and schema_info.type == sch.TYPE_MANIFEST:
|
||||||
is_valid, details = _validate_armada_manifest(manifest)
|
target = document.get('metadata').get('name')
|
||||||
all_valid = all_valid and is_valid
|
# TODO(MarshM) explore: why does this pass 'documents'?
|
||||||
messages.extend(details)
|
manifest = Manifest(documents, target_manifest=target)
|
||||||
|
is_valid, details = _validate_armada_manifest(manifest)
|
||||||
|
all_valid = all_valid and is_valid
|
||||||
|
messages.extend(details)
|
||||||
|
|
||||||
return all_valid, messages
|
return all_valid, messages
|
||||||
|
|
||||||
|
@ -151,9 +107,10 @@ def validate_armada_document(document):
|
||||||
details = []
|
details = []
|
||||||
LOG.debug('Validating document [%s] %s', schema, document_name)
|
LOG.debug('Validating document [%s] %s', schema, document_name)
|
||||||
|
|
||||||
if schema in SCHEMAS:
|
schema_info = sch.get_schema_info(schema)
|
||||||
|
if schema_info:
|
||||||
try:
|
try:
|
||||||
validator = jsonschema.Draft4Validator(SCHEMAS[schema])
|
validator = jsonschema.Draft4Validator(schema_info.data)
|
||||||
for error in validator.iter_errors(document.get('data')):
|
for error in validator.iter_errors(document.get('data')):
|
||||||
error_message = "Invalid document [%s] %s: %s." % \
|
error_message = "Invalid document [%s] %s: %s." % \
|
||||||
(schema, document_name, error.message)
|
(schema, document_name, error.message)
|
||||||
|
@ -222,7 +179,3 @@ def validate_manifest_url(value):
|
||||||
return (requests.get(value).status_code == 200)
|
return (requests.get(value).status_code == 200)
|
||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# Fill the cache.
|
|
||||||
_load_schemas()
|
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
..
|
||||||
|
Copyright 2019 AT&T Intellectual Property.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
Document Authoring Guide
|
||||||
|
========================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Contents:
|
||||||
|
|
||||||
|
v1/index
|
||||||
|
v2/index
|
||||||
|
migration-v1-v2
|
|
@ -0,0 +1,70 @@
|
||||||
|
..
|
||||||
|
Copyright 2019 AT&T Intellectual Property.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
v1-v2 Migration
|
||||||
|
===============
|
||||||
|
|
||||||
|
The following migrations must be done when moving from :ref:`v1 <document_authoring_v1>` to :ref:`v2 <document_authoring_v2>` docs.
|
||||||
|
|
||||||
|
Chart
|
||||||
|
-----
|
||||||
|
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| change | migration |
|
||||||
|
+================================+============================================================+
|
||||||
|
| ``chart_name`` removed | Remove. It was redundant with ``metadata.name`` while at |
|
||||||
|
| | the same time not guaranteeing uniqueness. Log messages now|
|
||||||
|
| | reference ``metadata.name`` for improved grep-ability. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``test`` as a boolean removed | :ref:`test <test_v2>` must now be an object. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``timeout`` removed | Use ``wait.timeout`` instead. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``install`` removed | Remove. Previously unused. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``upgrade.post`` removed | Remove. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``upgrade.pre.update`` removed | Remove. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``upgrade.pre.create`` removed | Remove. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``upgrade.pre.delete[*].name`` | Remove. |
|
||||||
|
| removed | |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``upgrade.pre.delete[*]`` | If you have an item in ``upgrade.pre.delete`` and |
|
||||||
|
| with ``type: job`` no longer | ``type: job`` and you also want to delete cronjobs, add |
|
||||||
|
| deletes cronjobs | another item with ``type: cronjob`` and same labels. |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
| ``dependencies``, | Remove as desired. |
|
||||||
|
| ``upgrade.no_hooks``, | |
|
||||||
|
| ``source.subpath`` | |
|
||||||
|
| now optional | |
|
||||||
|
+--------------------------------+------------------------------------------------------------+
|
||||||
|
|
||||||
|
ChartGroup
|
||||||
|
----------
|
||||||
|
|
||||||
|
+--------------------------+-----------------------------------------------------------+
|
||||||
|
| change | migration |
|
||||||
|
+==========================+===========================================================+
|
||||||
|
| ``test_charts`` removed | Use the Chart schema's :ref:`test.enabled <test_v2>` |
|
||||||
|
| | instead. |
|
||||||
|
+--------------------------+-----------------------------------------------------------+
|
||||||
|
|
||||||
|
Manifest
|
||||||
|
--------
|
||||||
|
|
||||||
|
No changes.
|
|
@ -1,5 +1,23 @@
|
||||||
Armada - Making Your First Armada Manifest
|
..
|
||||||
==========================================
|
Copyright 2019 AT&T Intellectual Property.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
.. _document_authoring_v1:
|
||||||
|
|
||||||
|
v1 Authoring
|
||||||
|
============
|
||||||
|
|
||||||
armada/Manifest/v1
|
armada/Manifest/v1
|
||||||
------------------
|
------------------
|
||||||
|
@ -191,9 +209,6 @@ Run helm tests on the chart after install/upgrade.
|
||||||
deprecated and will be removed. The ``cleanup`` option below is set to true
|
deprecated and will be removed. The ``cleanup`` option below is set to true
|
||||||
in this case for backward compatibility.
|
in this case for backward compatibility.
|
||||||
|
|
||||||
.. _test_options:
|
|
||||||
|
|
||||||
|
|
||||||
Test Options
|
Test Options
|
||||||
^^^^^^^^^^^^
|
^^^^^^^^^^^^
|
||||||
|
|
|
@ -0,0 +1,25 @@
|
||||||
|
..
|
||||||
|
Copyright 2019 AT&T Intellectual Property.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
v1
|
||||||
|
==
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Contents:
|
||||||
|
|
||||||
|
document-authoring
|
||||||
|
schemas
|
|
@ -14,15 +14,11 @@
|
||||||
License for the specific language governing permissions and limitations
|
License for the specific language governing permissions and limitations
|
||||||
under the License.
|
under the License.
|
||||||
|
|
||||||
.. _armada-documents:
|
v1 Schemas
|
||||||
|
==========
|
||||||
|
|
||||||
Armada Documents
|
Below are the schemas Armada uses to validate Charts, Chart Groups, and
|
||||||
================
|
Manifests.
|
||||||
|
|
||||||
Below are the schemas Armada uses to validate :ref:`Charts`,
|
|
||||||
:ref:`Chart Groups`, and :ref:`Manifests`.
|
|
||||||
|
|
||||||
.. _Charts:
|
|
||||||
|
|
||||||
Charts
|
Charts
|
||||||
------
|
------
|
||||||
|
@ -32,16 +28,12 @@ comparable to a Helm chart. Charts consist of all the labels, dependencies,
|
||||||
install and upgrade information, hooks and additional information needed to
|
install and upgrade information, hooks and additional information needed to
|
||||||
convey to Tiller.
|
convey to Tiller.
|
||||||
|
|
||||||
.. _Chart Groups:
|
|
||||||
|
|
||||||
Chart Groups
|
Chart Groups
|
||||||
------------
|
------------
|
||||||
|
|
||||||
A ``Chart Group`` consists of a list of charts. ``Chart Group`` documents are
|
A ``Chart Group`` consists of a list of charts. ``Chart Group`` documents are
|
||||||
useful for managing a group of ``Chart`` documents together.
|
useful for managing a group of ``Chart`` documents together.
|
||||||
|
|
||||||
.. _Manifests:
|
|
||||||
|
|
||||||
Manifests
|
Manifests
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -76,7 +68,7 @@ Schemas
|
||||||
``metadata.name`` are validated.
|
``metadata.name`` are validated.
|
||||||
|
|
||||||
.. literalinclude::
|
.. literalinclude::
|
||||||
../../../armada/schemas/armada-chart-schema.yaml
|
../../../../../armada/schemas/armada-chart-schema-v1.yaml
|
||||||
:language: yaml
|
:language: yaml
|
||||||
:lines: 15-
|
:lines: 15-
|
||||||
:caption: Schema for ``armada/Chart/v1`` documents.
|
:caption: Schema for ``armada/Chart/v1`` documents.
|
||||||
|
@ -90,7 +82,7 @@ Schemas
|
||||||
``metadata.name`` are validated.
|
``metadata.name`` are validated.
|
||||||
|
|
||||||
.. literalinclude::
|
.. literalinclude::
|
||||||
../../../armada/schemas/armada-chartgroup-schema.yaml
|
../../../../../armada/schemas/armada-chartgroup-schema-v1.yaml
|
||||||
:language: yaml
|
:language: yaml
|
||||||
:lines: 15-
|
:lines: 15-
|
||||||
:caption: Schema for ``armada/ChartGroup/v1`` documents.
|
:caption: Schema for ``armada/ChartGroup/v1`` documents.
|
||||||
|
@ -104,7 +96,7 @@ Schemas
|
||||||
``metadata.name`` are validated.
|
``metadata.name`` are validated.
|
||||||
|
|
||||||
.. literalinclude::
|
.. literalinclude::
|
||||||
../../../armada/schemas/armada-manifest-schema.yaml
|
../../../../../armada/schemas/armada-manifest-schema-v1.yaml
|
||||||
:language: yaml
|
:language: yaml
|
||||||
:lines: 15-
|
:lines: 15-
|
||||||
:caption: Schema for ``armada/Manifest/v1`` documents.
|
:caption: Schema for ``armada/Manifest/v1`` documents.
|
||||||
|
@ -112,8 +104,6 @@ Schemas
|
||||||
This schema is used to sanity-check all ``Manifest`` documents that are passed
|
This schema is used to sanity-check all ``Manifest`` documents that are passed
|
||||||
to Armada.
|
to Armada.
|
||||||
|
|
||||||
.. _authoring-guidelines:
|
|
||||||
|
|
||||||
Authoring Guidelines
|
Authoring Guidelines
|
||||||
--------------------
|
--------------------
|
||||||
|
|
|
@ -0,0 +1,469 @@
|
||||||
|
..
|
||||||
|
Copyright 2019 AT&T Intellectual Property.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
.. _document_authoring_v2:
|
||||||
|
|
||||||
|
v2 Authoring
|
||||||
|
============
|
||||||
|
|
||||||
|
.. DANGER::
|
||||||
|
|
||||||
|
EXPERIMENTAL: `v2` docs are still experimental and WILL have breaking changes
|
||||||
|
before they are finalized.
|
||||||
|
|
||||||
|
armada/Manifest/v2
|
||||||
|
------------------
|
||||||
|
|
||||||
|
+---------------------+--------+-------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=====================+========+=========================+
|
||||||
|
| ``release_prefix`` | string | appends to the |
|
||||||
|
| | | front of all |
|
||||||
|
| | | charts |
|
||||||
|
| | | released |
|
||||||
|
| | | by the |
|
||||||
|
| | | manifest in |
|
||||||
|
| | | order to |
|
||||||
|
| | | manage releases |
|
||||||
|
| | | throughout their |
|
||||||
|
| | | lifecycle |
|
||||||
|
+---------------------+--------+-------------------------+
|
||||||
|
| ``chart_groups`` | array | A list of the |
|
||||||
|
| | | ``metadata.name`` of |
|
||||||
|
| | | each ``ChartGroup`` to |
|
||||||
|
| | | deploy in order. |
|
||||||
|
+---------------------+--------+-------------------------+
|
||||||
|
|
||||||
|
Manifest Example
|
||||||
|
^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
---
|
||||||
|
schema: armada/Manifest/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: simple-armada
|
||||||
|
data:
|
||||||
|
release_prefix: armada
|
||||||
|
chart_groups:
|
||||||
|
- chart_group
|
||||||
|
|
||||||
|
|
||||||
|
armada/ChartGroup/v2
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
+-----------------+----------+------------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=================+==========+========================================================================+
|
||||||
|
| description | string | description of chart set |
|
||||||
|
+-----------------+----------+------------------------------------------------------------------------+
|
||||||
|
| chart_group | array | A list of the ``metadata.name`` of each ``Chart`` to deploy. |
|
||||||
|
+-----------------+----------+------------------------------------------------------------------------+
|
||||||
|
| sequenced | bool | If ``true``, deploys each chart in sequence, else in parallel. |
|
||||||
|
| | | Default ``false``. |
|
||||||
|
+-----------------+----------+------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Chart Group Example
|
||||||
|
^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
---
|
||||||
|
schema: armada/ChartGroup/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-group
|
||||||
|
data:
|
||||||
|
description: Deploys Simple Service
|
||||||
|
chart_group:
|
||||||
|
- chart1
|
||||||
|
- chart2
|
||||||
|
|
||||||
|
armada/Chart/v2
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Chart
|
||||||
|
^^^^^
|
||||||
|
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=================+==========+=======================================================================================+
|
||||||
|
| release | string | name of the release (Armada will prepend with ``release-prefix`` during processing) |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| namespace | string | namespace of your chart |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| wait | object | See `Wait`_. |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| protected | object | do not delete FAILED releases when encountered from previous run (provide the |
|
||||||
|
| | | 'continue_processing' bool to continue or halt execution (default: halt)) |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| test | object | See Test_. |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| upgrade | object | upgrade the chart managed by the armada yaml |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| delete | object | See Delete_. |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| values | object | (optional) override any default values in the charts |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| source | object | provide a path to a ``git repo``, ``local dir``, or ``tarball url`` chart |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
| dependencies | object | (optional) reference any chart dependencies before install |
|
||||||
|
+-----------------+----------+---------------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Wait
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+====================================================================+
|
||||||
|
| timeout | int | time (in seconds) to wait for chart to deploy |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| resources | array | Array of `Wait Resource`_ to wait on, with ``labels`` added to each|
|
||||||
|
| | | item. Defaults to pods and jobs (if any exist) matching ``labels``.|
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| labels | object | Base mapping of labels to wait on. They are added to any labels in |
|
||||||
|
| | | each item in the ``resources`` array. |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| native | boolean | See `Wait Native`_. |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Wait Resource
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+====================================================================+
|
||||||
|
| type | string | k8s resource type, supports: controllers ('deployment', |
|
||||||
|
| | | 'daemonset', 'statefulset'), 'pod', 'job' |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| labels | object | mapping of kubernetes resource labels |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| min\_ready | int | Only for controller ``type``s. Amount of pods in a controller |
|
||||||
|
| | string | which must be ready. Can be integer or percent string e.g. ``80%``.|
|
||||||
|
| | | Default ``100%``. |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Wait Native
|
||||||
|
^^^^^^^^^^^
|
||||||
|
|
||||||
|
Config for the native ``helm (install|upgrade) --wait`` flag.
|
||||||
|
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+====================================================================+
|
||||||
|
| enabled | boolean | defaults to true |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
.. _test_v2:
|
||||||
|
|
||||||
|
Test
|
||||||
|
^^^^
|
||||||
|
|
||||||
|
Run helm tests on the chart after install/upgrade.
|
||||||
|
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+====================================================================+
|
||||||
|
| enabled | bool | whether to enable/disable helm tests for this chart (default True) |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| timeout | int | time (in sec) to wait for completion of Helm tests |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
| options | object | See `Test Options`_. |
|
||||||
|
+-------------+----------+--------------------------------------------------------------------+
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Armada will attempt to run helm tests by default. They may be disabled by
|
||||||
|
setting the ``enabled`` key to ``False``.
|
||||||
|
|
||||||
|
Test Options
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
Test options to pass through directly to helm.
|
||||||
|
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+===============================================================+
|
||||||
|
| cleanup | bool | cleanup test pods after test completion, defaults to false |
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
If cleanup is ``true`` this prevents being able to debug a test in the event of failure.
|
||||||
|
|
||||||
|
Historically, the preferred way to achieve test cleanup has been to add a pre-upgrade delete
|
||||||
|
action on the test pod.
|
||||||
|
|
||||||
|
This still works, however it is usually no longer necessary as Armada now automatically
|
||||||
|
cleans up any test pods which match the ``wait.labels`` of the chart, immediately before
|
||||||
|
running tests. Similar suggestions have been made for how ``helm test --cleanup`` itself
|
||||||
|
ought to work (https://github.com/helm/helm/issues/3279).
|
||||||
|
|
||||||
|
Upgrade - Pre
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+===============================================================+
|
||||||
|
| pre | object | actions performed prior to updating a release |
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
|
||||||
|
Upgrade - Actions
|
||||||
|
^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+===============================================================+
|
||||||
|
| delete | array | List of `Upgrade - Actions - Delete`_. |
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
|
||||||
|
Upgrade - Actions - Delete
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+===============================================================+
|
||||||
|
| type | string | type of kubernetes resource to delete |
|
||||||
|
| | | supported types are: 'pod', 'job', 'cronjob'. |
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
| labels | object | k:v mapping of labels to select Kubernetes resources |
|
||||||
|
+-------------+----------+---------------------------------------------------------------+
|
||||||
|
|
||||||
|
Chart Example
|
||||||
|
^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-1
|
||||||
|
data:
|
||||||
|
release: blog-1
|
||||||
|
namespace: default
|
||||||
|
wait:
|
||||||
|
timeout: 100
|
||||||
|
protected:
|
||||||
|
continue_processing: false
|
||||||
|
test:
|
||||||
|
enabled: true
|
||||||
|
upgrade:
|
||||||
|
pre:
|
||||||
|
delete:
|
||||||
|
- name: test-job
|
||||||
|
type: job
|
||||||
|
labels:
|
||||||
|
foo: bar
|
||||||
|
component: bar
|
||||||
|
rak1: enabled
|
||||||
|
source:
|
||||||
|
type: git
|
||||||
|
location: https://github.com/namespace/repo
|
||||||
|
reference: master
|
||||||
|
|
||||||
|
Delete
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+===================================================================================+
|
||||||
|
| timeout | integer | time (in seconds) to wait for chart to be deleted |
|
||||||
|
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Source
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||||
|
| keyword | type | action |
|
||||||
|
+=============+==========+===================================================================================+
|
||||||
|
| type | string | source to build the chart: ``git``, ``local``, or ``tar`` |
|
||||||
|
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||||
|
| location | string | ``url`` or ``path`` to the chart's parent directory |
|
||||||
|
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||||
|
| subpath | string | (optional) relative path to target chart from parent (``.`` if not specified) |
|
||||||
|
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||||
|
| reference | string | (optional) branch, commit, or reference in the repo (``master`` if not specified) |
|
||||||
|
+-------------+----------+-----------------------------------------------------------------------------------+
|
||||||
|
|
||||||
|
Source Example
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
# type git
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-1
|
||||||
|
data:
|
||||||
|
release: blog-1
|
||||||
|
namespace: default
|
||||||
|
wait:
|
||||||
|
timeout: 100
|
||||||
|
labels:
|
||||||
|
component: blog
|
||||||
|
source:
|
||||||
|
type: git
|
||||||
|
location: https://github.com/namespace/repo
|
||||||
|
|
||||||
|
# type local
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-1
|
||||||
|
data:
|
||||||
|
release: blog-1
|
||||||
|
namespace: default
|
||||||
|
wait:
|
||||||
|
timeout: 100
|
||||||
|
source:
|
||||||
|
type: local
|
||||||
|
location: /path/to/charts
|
||||||
|
subpath: chart
|
||||||
|
reference: master
|
||||||
|
|
||||||
|
# type tar
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-1
|
||||||
|
data:
|
||||||
|
release: blog-1
|
||||||
|
namespace: default
|
||||||
|
wait:
|
||||||
|
timeout: 100
|
||||||
|
source:
|
||||||
|
type: tar
|
||||||
|
location: https://localhost:8879/charts/chart-0.1.0.tgz
|
||||||
|
subpath: mariadb
|
||||||
|
|
||||||
|
Simple Example
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-1
|
||||||
|
data:
|
||||||
|
release: blog-1
|
||||||
|
namespace: default
|
||||||
|
source:
|
||||||
|
type: git
|
||||||
|
location: https://github.com/namespace/repo
|
||||||
|
subpath: blog-1
|
||||||
|
reference: new-feat
|
||||||
|
---
|
||||||
|
schema: armada/ChartGroup/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-group
|
||||||
|
data:
|
||||||
|
description: Deploys Simple Service
|
||||||
|
chart_group:
|
||||||
|
- blog-1
|
||||||
|
---
|
||||||
|
schema: armada/Manifest/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: simple-armada
|
||||||
|
data:
|
||||||
|
release_prefix: armada
|
||||||
|
chart_groups:
|
||||||
|
- blog-group
|
||||||
|
|
||||||
|
Multichart Example
|
||||||
|
^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-1
|
||||||
|
data:
|
||||||
|
release: blog-1
|
||||||
|
namespace: default
|
||||||
|
source:
|
||||||
|
type: git
|
||||||
|
location: https://github.com/namespace/repo
|
||||||
|
subpath: blog1
|
||||||
|
reference: master
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-2
|
||||||
|
data:
|
||||||
|
release: blog-2
|
||||||
|
namespace: default
|
||||||
|
source:
|
||||||
|
type: tar
|
||||||
|
location: https://github.com/namespace/repo/blog2.tgz
|
||||||
|
subpath: blog2
|
||||||
|
---
|
||||||
|
schema: armada/Chart/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-3
|
||||||
|
data:
|
||||||
|
release: blog-3
|
||||||
|
namespace: default
|
||||||
|
source:
|
||||||
|
type: local
|
||||||
|
location: /home/user/namespace/repo/blog3
|
||||||
|
---
|
||||||
|
schema: armada/ChartGroup/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-group-1
|
||||||
|
data:
|
||||||
|
description: Deploys Simple Service
|
||||||
|
chart_group:
|
||||||
|
- blog-2
|
||||||
|
---
|
||||||
|
schema: armada/ChartGroup/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: blog-group-2
|
||||||
|
data:
|
||||||
|
description: Deploys Simple Service
|
||||||
|
chart_group:
|
||||||
|
- blog-1
|
||||||
|
- blog-3
|
||||||
|
---
|
||||||
|
schema: armada/Manifest/v2
|
||||||
|
metadata:
|
||||||
|
schema: metadata/Document/v1
|
||||||
|
name: simple-armada
|
||||||
|
data:
|
||||||
|
release_prefix: armada
|
||||||
|
chart_groups:
|
||||||
|
- blog-group-1
|
||||||
|
- blog-group-2
|
||||||
|
|
||||||
|
References
|
||||||
|
~~~~~~~~~~
|
||||||
|
|
||||||
|
For working examples please check the examples in our repo
|
||||||
|
`here <https://github.com/openstack/airship-armada/tree/master/examples>`__
|
|
@ -0,0 +1,25 @@
|
||||||
|
..
|
||||||
|
Copyright 2019 AT&T Intellectual Property.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
v2 (EXPERIMENTAL!)
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
:caption: Contents:
|
||||||
|
|
||||||
|
document-authoring
|
||||||
|
schemas
|
|
@ -0,0 +1,114 @@
|
||||||
|
..
|
||||||
|
Copyright 2018 AT&T Intellectual Property.
|
||||||
|
All Rights Reserved.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
not use this file except in compliance with the License. You may obtain
|
||||||
|
a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
License for the specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
|
||||||
|
v2 Schemas
|
||||||
|
==========
|
||||||
|
|
||||||
|
Below are the schemas Armada uses to validate Charts, Chart Groups, and
|
||||||
|
Manifests.
|
||||||
|
|
||||||
|
Charts
|
||||||
|
------
|
||||||
|
|
||||||
|
Charts consist of the smallest building blocks in Armada. A ``Chart`` is
|
||||||
|
comparable to a Helm chart. Charts consist of all the labels, dependencies,
|
||||||
|
install and upgrade information, hooks and additional information needed to
|
||||||
|
convey to Tiller.
|
||||||
|
|
||||||
|
Chart Groups
|
||||||
|
------------
|
||||||
|
|
||||||
|
A ``Chart Group`` consists of a list of charts. ``Chart Group`` documents are
|
||||||
|
useful for managing a group of ``Chart`` documents together.
|
||||||
|
|
||||||
|
Manifests
|
||||||
|
---------
|
||||||
|
|
||||||
|
A ``Manifest`` is the largest building block in Armada. ``Manifest`` documents
|
||||||
|
are responsible for managing collections of ``Chart Group`` documents.
|
||||||
|
|
||||||
|
Validation Schemas
|
||||||
|
------------------
|
||||||
|
|
||||||
|
Introduction
|
||||||
|
^^^^^^^^^^^^
|
||||||
|
|
||||||
|
All schemas below are `Deckhand DataSchema`_ documents, which are essentially
|
||||||
|
JSON schemas, with additional metadata useful for Deckhand to perform
|
||||||
|
`layering`_ and `substitution`_.
|
||||||
|
|
||||||
|
The validation schemas below are used by Armada to validate all ingested
|
||||||
|
Charts, Chart Groups, and Manifests. Use the schemas below as models for
|
||||||
|
authoring Armada documents.
|
||||||
|
|
||||||
|
.. _Deckhand DataSchema: https://airship-deckhand.readthedocs.io/en/latest/document-types.html?highlight=dataschema#dataschema
|
||||||
|
.. _Helm charts: https://docs.helm.sh/developing_charts/
|
||||||
|
.. _layering: https://airship-deckhand.readthedocs.io/en/latest/layering.html
|
||||||
|
.. _substitution: https://airship-deckhand.readthedocs.io/en/latest/substitution.html
|
||||||
|
|
||||||
|
Schemas
|
||||||
|
^^^^^^^
|
||||||
|
|
||||||
|
* ``Chart`` schema.
|
||||||
|
|
||||||
|
JSON schema against which all documents with ``armada/Chart/v2``
|
||||||
|
``metadata.name`` are validated.
|
||||||
|
|
||||||
|
.. literalinclude::
|
||||||
|
../../../../../armada/schemas/armada-chart-schema-v2.yaml
|
||||||
|
:language: yaml
|
||||||
|
:lines: 15-
|
||||||
|
:caption: Schema for ``armada/Chart/v2`` documents.
|
||||||
|
|
||||||
|
This schema is used to sanity-check all ``Chart`` documents that are passed
|
||||||
|
to Armada.
|
||||||
|
|
||||||
|
* ``Chart Group`` schema.
|
||||||
|
|
||||||
|
JSON schema against which all documents with ``armada/Chart/v2``
|
||||||
|
``metadata.name`` are validated.
|
||||||
|
|
||||||
|
.. literalinclude::
|
||||||
|
../../../../../armada/schemas/armada-chartgroup-schema-v2.yaml
|
||||||
|
:language: yaml
|
||||||
|
:lines: 15-
|
||||||
|
:caption: Schema for ``armada/ChartGroup/v2`` documents.
|
||||||
|
|
||||||
|
This schema is used to sanity-check all ``Chart Group`` documents that are
|
||||||
|
passed to Armada.
|
||||||
|
|
||||||
|
* ``Manifest`` schema.
|
||||||
|
|
||||||
|
JSON schema against which all documents with ``armada/Manifest/v2``
|
||||||
|
``metadata.name`` are validated.
|
||||||
|
|
||||||
|
.. literalinclude::
|
||||||
|
../../../../../armada/schemas/armada-manifest-schema-v2.yaml
|
||||||
|
:language: yaml
|
||||||
|
:lines: 15-
|
||||||
|
:caption: Schema for ``armada/Manifest/v2`` documents.
|
||||||
|
|
||||||
|
This schema is used to sanity-check all ``Manifest`` documents that are passed
|
||||||
|
to Armada.
|
||||||
|
|
||||||
|
Authoring Guidelines
|
||||||
|
--------------------
|
||||||
|
|
||||||
|
All Armada documents must use the ``deckhand/DataSchema/v1`` schema.
|
||||||
|
|
||||||
|
.. todo::
|
||||||
|
|
||||||
|
Expand on this section.
|
|
@ -10,7 +10,9 @@ Kubernetes Cluster
|
||||||
|
|
||||||
`Tiller Service <https://github.com/kubernetes/helm>`_
|
`Tiller Service <https://github.com/kubernetes/helm>`_
|
||||||
|
|
||||||
`Armada.yaml <https://airship-armada.readthedocs.io/en/latest/operations/guide-build-armada-yaml.html>`_
|
.. todo:: point this to v2 docs once they're stable
|
||||||
|
|
||||||
|
:ref:`Armada documents <document_authoring_v1>`
|
||||||
|
|
||||||
.. note::
|
.. note::
|
||||||
|
|
||||||
|
|
|
@ -10,11 +10,10 @@ Operations Guide
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
:caption: Contents:
|
:caption: Contents:
|
||||||
|
|
||||||
guide-build-armada-yaml
|
documents/index
|
||||||
guide-configure
|
guide-configure
|
||||||
guide-troubleshooting
|
guide-troubleshooting
|
||||||
guide-use-armada
|
guide-use-armada
|
||||||
documents
|
|
||||||
exceptions/index
|
exceptions/index
|
||||||
guide-helm-plugin
|
guide-helm-plugin
|
||||||
sampleconf
|
sampleconf
|
||||||
|
|
Loading…
Reference in New Issue