Revert "Airship 2 support features"

This reverts commit c75898cd6a.

Airship 2 ended up using the Flux helm-controller instead:
https://github.com/fluxcd/helm-controller

So this is no longer needed. Removing it to get rid of tech
debt to ease introduction of Helm 3 support.

This retains the part of the commit which extracts the
chart download logic to its own handler as this is still useful.

Change-Id: Icb468be2d4916620fd78df250fd038ab58840182
This commit is contained in:
Sean Eagan 2021-07-19 13:34:01 -05:00
parent b37417253f
commit 5f1ffbbbbe
28 changed files with 87 additions and 1140 deletions

View File

@ -25,7 +25,6 @@
- armada-docker-build-gate-ubuntu_xenial
- armada-docker-build-gate-opensuse
- armada-airskiff-deploy
- armada-airship2-integration
gate:
jobs:
- openstack-tox-docs
@ -129,26 +128,6 @@
- ^releasenotes/.*$
- ^swagger/.*$
- job:
name: armada-airship2-integration
nodeset: armada-single-node
description: |
Deploy basic airship2 integration example using submitted Armada changes.
timeout: 9600
voting: false
pre-run:
- tools/gate/playbooks/git-config.yaml
run: tools/gate/playbooks/airship2-integration.yaml
post-run: tools/gate/playbooks/debug-report.yaml
required-projects:
- airship/treasuremap
irrelevant-files:
- ^.*\.rst$
- ^doc/.*$
- ^examples/.*$
- ^releasenotes/.*$
- ^swagger/.*$
- job:
name: armada-docker-publish-ubuntu_bionic
timeout: 1800

View File

@ -1,207 +0,0 @@
# Copyright 2020 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 click
from oslo_config import cfg
import prometheus_client
import yaml
from armada.cli import CliAction
from armada.exceptions.source_exceptions import InvalidPathException
from armada.handlers import metrics
from armada.handlers.chart_deploy import ChartDeploy
from armada.handlers.chart_download import ChartDownload
from armada.handlers.document import ReferenceResolver
from armada.handlers.lock import lock_and_thread
from armada.handlers.manifest import Chart
from armada.handlers.tiller import Tiller
CONF = cfg.CONF
@click.group()
def apply_chart():
""" Apply chart to cluster
"""
DESC = """
This command installs and updates an Armada chart.
[LOCATION] must be a relative path to Armada Chart or a reference
to an Armada Chart kubernetes CR which has the same format, except as
noted in the v2 document authoring documentation.
To install or upgrade a chart, run:
\b
$ armada apply_chart --release-prefix=armada my-chart.yaml
$ armada apply_chart --release-prefix=armada \
kube:armadacharts/my-namespace/my-chart
"""
SHORT_DESC = "Command deploys a chart."
@apply_chart.command(name='apply_chart', help=DESC, short_help=SHORT_DESC)
@click.argument('location')
@click.option(
'--release-prefix',
help="Prefix to prepend to chart release name.",
required=True)
@click.option(
'--disable-update-post',
help="Disable post-update Tiller operations.",
is_flag=True)
@click.option(
'--disable-update-pre',
help="Disable pre-update Tiller operations.",
is_flag=True)
@click.option(
'--metrics-output',
help=(
"Output path for prometheus metric data, should end in .prom. By "
"default, no metric data is output."),
default=None)
@click.option('--tiller-host', help="Tiller host IP.", default=None)
@click.option(
'--tiller-port', help="Tiller host port.", type=int, default=None)
@click.option(
'--tiller-namespace',
'-tn',
help="Tiller namespace.",
type=str,
default=None)
@click.option(
'--timeout',
help="Specifies time to wait for each chart to fully "
"finish deploying.",
type=int)
@click.option(
'--wait',
help=(
"Force Tiller to wait until the chart is deployed, "
"rather than using the chart's specified wait policy. "
"This is equivalent to sequenced chartgroups."),
is_flag=True)
@click.option(
'--target-chart',
help=(
"The target chart to deploy. Required for specifying "
"which chart to deploy when multiple are available."),
default=None)
@click.option('--bearer-token', help="User Bearer token", default=None)
@click.option('--debug', help="Enable debug logging.", is_flag=True)
@click.pass_context
def apply_chart(
ctx, location, release_prefix, disable_update_post, disable_update_pre,
metrics_output, tiller_host, tiller_port, tiller_namespace, timeout,
wait, target_chart, bearer_token, debug):
CONF.debug = debug
ApplyChart(
ctx, location, release_prefix, disable_update_post, disable_update_pre,
metrics_output, tiller_host, tiller_port, tiller_namespace, timeout,
wait, target_chart, bearer_token).safe_invoke()
class ApplyChart(CliAction):
def __init__(
self, ctx, location, release_prefix, disable_update_post,
disable_update_pre, metrics_output, tiller_host, tiller_port,
tiller_namespace, timeout, wait, target_chart, bearer_token):
super(ApplyChart, self).__init__()
self.ctx = ctx
self.release_prefix = release_prefix
# Filename can also be a URL reference
self.location = location
self.disable_update_post = disable_update_post
self.disable_update_pre = disable_update_pre
self.metrics_output = metrics_output
self.tiller_host = tiller_host
self.tiller_port = tiller_port
self.tiller_namespace = tiller_namespace
self.timeout = timeout
self.target_chart = target_chart
self.bearer_token = bearer_token
def output(self, resp):
for result in resp:
if not resp[result] and not result == 'diff':
self.logger.info('Did not perform chart %s(s)', result)
elif result == 'diff' and not resp[result]:
self.logger.info('No release changes detected')
ch = resp[result]
if not result == 'diff':
msg = 'Chart {} took action: {}'.format(ch, result)
if result == 'protected':
msg += ' and requires operator attention.'
elif result == 'purge':
msg += ' before install/upgrade.'
self.logger.info(msg)
else:
self.logger.info('Chart/values diff: %s', ch)
def invoke(self):
with Tiller(tiller_host=self.tiller_host, tiller_port=self.tiller_port,
tiller_namespace=self.tiller_namespace,
bearer_token=self.bearer_token) as tiller:
try:
doc_data = ReferenceResolver.resolve_reference(
self.location, k8s=tiller.k8s)
documents = list()
for d in doc_data:
documents.extend(list(yaml.safe_load_all(d.decode())))
except InvalidPathException as ex:
self.logger.error(str(ex))
return
except yaml.YAMLError as yex:
self.logger.error("Invalid YAML found: %s" % str(yex))
return
try:
resp = self.handle(documents, tiller)
self.output(resp)
finally:
if self.metrics_output:
path = self.metrics_output
self.logger.info(
'Storing metrics output in path: {}'.format(path))
prometheus_client.write_to_textfile(path, metrics.REGISTRY)
def handle(self, documents, tiller):
chart = Chart(documents, target_chart=self.target_chart).get_chart()
lock_name = 'chart-{}'.format(chart['metadata']['name'])
@lock_and_thread(lock_name)
def _handle():
chart_download = ChartDownload()
try:
chart_download.get_chart(chart)
chart_deploy = ChartDeploy(
None, self.disable_update_pre, self.disable_update_post, 1,
1, self.timeout, tiller)
# TODO: Only get release with matching name.
known_releases = tiller.list_releases()
return chart_deploy.execute(
chart, None, self.release_prefix, known_releases, 1)
finally:
chart_download.cleanup()
return _handle()

View File

@ -47,16 +47,14 @@ class ChartDeploy(object):
def execute(
self, ch, cg_test_all_charts, prefix, known_releases, concurrency):
chart_name = ch['metadata']['name']
manifest_name = self.manifest['metadata'][
'name'] if self.manifest else ''
manifest_name = self.manifest['metadata']['name']
with metrics.CHART_HANDLE.get_context(concurrency, manifest_name,
chart_name):
return self._execute(
ch, cg_test_all_charts, prefix, known_releases)
def _execute(self, ch, cg_test_all_charts, prefix, known_releases):
manifest_name = self.manifest['metadata'][
'name'] if self.manifest else ''
manifest_name = self.manifest['metadata']['name']
chart = ch[const.KEYWORD_DATA]
chart_name = ch['metadata']['name']
namespace = chart.get('namespace')

View File

@ -17,10 +17,8 @@
import urllib.parse
import re
from oslo_log import log as logging
import requests
import yaml
from kubernetes.client.rest import ApiException
from oslo_log import log as logging
from armada.exceptions.source_exceptions import InvalidPathException
from armada.utils import keystone as ks_utils
@ -32,7 +30,7 @@ class ReferenceResolver(object):
"""Class for handling different data references to resolve the data."""
@classmethod
def resolve_reference(cls, design_ref, k8s=None):
def resolve_reference(cls, design_ref):
"""Resolve a reference to a design document.
Locate a schema handler based on the URI scheme of the data reference
@ -53,16 +51,10 @@ class ReferenceResolver(object):
# when scheme is a empty string assume it is a local
# file path
scheme = design_uri.scheme or 'file'
handler = cls.scheme_handlers.get(scheme, None)
handler = handler.__get__(None, cls)
if design_uri.scheme == 'kube':
handler_2 = handler
def handler_1(design_uri):
return handler_2(design_uri, k8s)
handler = handler_1
if design_uri.scheme == '':
handler = cls.scheme_handlers.get('file')
else:
handler = cls.scheme_handlers.get(design_uri.scheme, None)
if handler is None:
raise InvalidPathException(
@ -79,50 +71,6 @@ class ReferenceResolver(object):
return data
@classmethod
def resolve_reference_kube(cls, design_uri, k8s):
"""Retrieve design documents from kubernetes crd.
Return the result of converting the CRD to the armada/Chart/v2 schema.
:param design_uri: Tuple as returned by urllib.parse
for the design reference
"""
if design_uri.path != '':
parts = design_uri.path.split('/')
if len(parts) != 3:
raise InvalidPathException(
"Invalid kubernetes custom resource path segment count {} "
"for '{}', expected <kind>/<namespace>/<name>".format(
len(parts), design_uri.path))
plural, namespace, name = parts
if plural != 'armadacharts':
raise InvalidPathException(
"Invalid kubernetes custom resource kind '{}' for '{}', "
"only 'armadacharts' are supported".format(
plural, design_uri.path))
try:
cr = k8s.read_custom_resource(
group='armada.airshipit.org',
version='v1alpha1',
namespace=namespace,
plural=plural,
name=name)
except ApiException as err:
if err.status == 404:
raise InvalidPathException(
"Kubernetes custom resource not found: plural='{}', "
"namespace='{}', name='{}', api exception=\n{}".format(
plural, namespace, name, err.message))
raise
cr['schema'] = 'armada/Chart/v2'
spec = cr.pop('spec')
cr['data'] = spec
return yaml.safe_dump(cr, encoding='utf-8')
@classmethod
def resolve_reference_http(cls, design_uri):
"""Retrieve design documents from http/https endpoints.
@ -186,7 +134,6 @@ class ReferenceResolver(object):
return resp.content
scheme_handlers = {
'kube': resolve_reference_kube,
'http': resolve_reference_http,
'file': resolve_reference_file,
'https': resolve_reference_http,

View File

@ -22,12 +22,56 @@ from armada.handlers import schema
LOG = logging.getLogger(__name__)
class Doc(object):
def __init__(self, documents):
self.documents = deepcopy(documents)
self.charts, self.groups, self.manifests = self._find_documents()
class Manifest(object):
def __init__(self, documents, target_manifest=None):
"""Instantiates a Manifest object.
def _find_documents(self):
An Armada Manifest expects that at least one of each of the following
be included in ``documents``:
* A document with schema "armada/Chart/v1"
* A document with schema "armada/ChartGroup/v1"
And only one document of the following is allowed:
* A document with schema "armada/Manifest/v1"
If multiple documents with schema "armada/Manifest/v1" are provided,
specify ``target_manifest`` to select the target one.
:param List[dict] documents: Documents out of which to build the
Armada Manifest.
:param str target_manifest: The target manifest to use when multiple
documents with "armada/Manifest/v1" are contained in
``documents``. Default is None.
:raises ManifestException: If the expected number of document types
are not found or if the document types are missing required
properties.
"""
self.documents = deepcopy(documents)
self.charts, self.groups, manifests = self._find_documents(
target_manifest)
if len(manifests) > 1:
error = (
'Multiple manifests are not supported. Ensure that the '
'`target_manifest` option is set to specify the target '
'manifest')
LOG.error(error)
raise exceptions.ManifestException(details=error)
else:
self.manifest = manifests[0] if manifests else None
if not all([self.charts, self.groups, self.manifest]):
expected_schemas = [schema.TYPE_CHART, schema.TYPE_CHARTGROUP]
error = (
'Documents must include at least one of each of {} '
'and only one {}').format(
expected_schemas, schema.TYPE_MANIFEST)
LOG.error(error)
raise exceptions.ManifestException(details=error)
def _find_documents(self, target_manifest=None):
"""Returns the chart documents, chart group documents,
and Armada manifest
@ -53,44 +97,14 @@ class Doc(object):
if schema_info.type == schema.TYPE_CHARTGROUP:
groups.append(document)
if schema_info.type == schema.TYPE_MANIFEST:
manifests.append(document)
manifest_name = document.get('metadata', {}).get('name')
if target_manifest:
if manifest_name == target_manifest:
manifests.append(document)
else:
manifests.append(document)
return charts, groups, manifests
def _get_target_doc(self, sch, documents, target, target_arg_name):
"""Validates there is exactly one document of a given schema and
optionally name and returns it.
:param sch: Schema which corresponds to `documents`.
:param documents: Documents which correspond to `sch`.
:param target: The target document name of schema `sch` to return.
Default is None.
:raises ManifestException: If `target` is None and multiple `documents`
are passed, or if no documents are found matching the parameters.
"""
candidates = []
for manifest in documents:
if target:
manifest_name = manifest.get('metadata', {}).get('name')
if manifest_name == target:
candidates.append(manifest)
else:
candidates.append(manifest)
if len(candidates) > 1:
error = (
'Multiple {} documents are not supported. Ensure that the '
'`{}` option is set to specify the target one').format(
sch, target_arg_name)
LOG.error(error)
raise exceptions.ManifestException(details=error)
if not candidates:
error = 'Documents must include at least one {}'.format(sch)
LOG.error(error)
raise exceptions.ManifestException(details=error)
return candidates[0]
def find_chart_document(self, name):
"""Returns a chart document with the specified name
@ -107,6 +121,22 @@ class Doc(object):
details='Could not find {} named "{}"'.format(
schema.TYPE_CHART, name))
def find_chart_group_document(self, name):
"""Returns a chart group document with the specified name
:param str name: name of the desired chart group document
:returns: The requested chart group document
:rtype: dict
:raises ManifestException: If a chart
group document with the specified name is not found
"""
for group in self.groups:
if group.get('metadata', {}).get('name') == name:
return group
raise exceptions.BuildChartGroupException(
details='Could not find {} named "{}"'.format(
schema.TYPE_CHARTGROUP, name))
def build_chart_deps(self, chart):
"""Recursively build chart dependencies for ``chart``.
@ -134,90 +164,6 @@ class Doc(object):
else:
return chart
class Chart(Doc):
def __init__(self, documents, target_chart=None):
"""A Chart expects the following be included in ``documents``:
* A document with schema "armada/Chart/v1"
If multiple Charts are provided, specify ``target_chart`` to select the
target one.
:param documents: Documents out of which to build the
Chart.
:param target_chart: The target Chart to use when multiple
Charts are contained in ``documents``. Default is None.
:raises ManifestException: If the expected number of document types
are not found or if the document types are missing required
properties.
"""
super(Chart, self).__init__(documents)
self.chart = self._get_target_doc(
schema.TYPE_CHART, self.documents, target_chart, 'target_chart')
def get_chart(self):
"""Builds the Chart
:returns: The Chart.
:rtype: dict
"""
self.build_chart_deps(self.chart)
return self.chart
class Manifest(Doc):
def __init__(self, documents, target_manifest=None):
"""An Armada Manifest expects that at least one of each of the following
be included in ``documents``:
* A document with schema "armada/Chart/v1"
* A document with schema "armada/ChartGroup/v1"
And only one document of the following is allowed:
* A document with schema "armada/Manifest/v1"
If multiple documents with schema "armada/Manifest/v1" are provided,
specify ``target_manifest`` to select the target one.
:param List[dict] documents: Documents out of which to build the
Armada Manifest.
:param str target_manifest: The target manifest to use when multiple
documents with "armada/Manifest/v1" are contained in
``documents``. Default is None.
:raises ManifestException: If the expected number of document types
are not found or if the document types are missing required
properties.
"""
super(Manifest, self).__init__(documents)
self.manifest = self._get_target_doc(
schema.TYPE_MANIFEST, self.manifests, target_manifest,
'target_manifest')
if not all([self.charts, self.groups]):
expected_schemas = [schema.TYPE_CHART, schema.TYPE_CHARTGROUP]
error = 'Documents must include at least one of each of {}'.format(
expected_schemas)
LOG.error(error)
raise exceptions.ManifestException(details=error)
def find_chart_group_document(self, name):
"""Returns a chart group document with the specified name
:param str name: name of the desired chart group document
:returns: The requested chart group document
:rtype: dict
:raises ManifestException: If a chart
group document with the specified name is not found
"""
for group in self.groups:
if group.get('metadata', {}).get('name') == name:
return group
raise exceptions.BuildChartGroupException(
details='Could not find {} named "{}"'.format(
schema.TYPE_CHARTGROUP, name))
def build_chart_group(self, chart_group):
"""Builds the chart dependencies for`charts`chart group``.

View File

@ -61,12 +61,6 @@ class ChartWait():
schema_info = get_schema_info(self.chart['schema'])
resources = self.wait_config.get('resources')
# wait.resources can be set to [] to disable all resource types, so
# don't override with defaults
if resources is None:
resources = self.wait_config.get('resources_list')
if isinstance(resources, list):
# Explicit resource config list provided.
resources_list = resources

View File

@ -19,7 +19,6 @@ from oslo_config import cfg
from oslo_log import log
from armada.cli.apply import apply_create
from armada.cli.apply_chart import apply_chart
from armada.cli.delete import delete_charts
from armada.cli.rollback import rollback_charts
from armada.cli.test import test_charts
@ -50,7 +49,6 @@ def main(ctx, debug, api, url, token):
\b
$ armada apply
$ armada apply_chart
$ armada delete
$ armada rollback
$ armada test
@ -90,7 +88,6 @@ def main(ctx, debug, api, url, token):
main.add_command(apply_create)
main.add_command(apply_chart)
main.add_command(delete_charts)
main.add_command(rollback_charts)
main.add_command(test_charts)

View File

@ -15,7 +15,7 @@
import copy
import os
import testtools
import testtools
import yaml
from armada import exceptions
@ -117,7 +117,7 @@ class ManifestTestCase(testtools.TestCase):
def test_find_documents(self):
armada_manifest = manifest.Manifest(self.documents)
chart_documents, chart_groups, manifests = armada_manifest. \
_find_documents()
_find_documents(target_manifest='armada-manifest')
# checking if all the chart documents are present
self.assertIsInstance(chart_documents, list)
@ -344,8 +344,7 @@ class ManifestNegativeTestCase(testtools.TestCase):
documents = copy.deepcopy(self.documents)
documents.append(documents[-1]) # Copy the last manifest.
error_re = r'Multiple {} documents are not supported.*'.format(
schema.TYPE_MANIFEST)
error_re = r'Multiple manifests are not supported.*'
self.assertRaisesRegexp(
exceptions.ManifestException, error_re, manifest.Manifest,
documents)
@ -356,8 +355,7 @@ class ManifestNegativeTestCase(testtools.TestCase):
documents = copy.deepcopy(self.documents)
documents.append(documents[-1]) # Copy the last manifest.
error_re = r'Multiple {} documents are not supported.*'.format(
schema.TYPE_MANIFEST)
error_re = r'Multiple manifests are not supported.*'
self.assertRaisesRegexp(
exceptions.ManifestException,
error_re,
@ -366,7 +364,9 @@ class ManifestNegativeTestCase(testtools.TestCase):
target_manifest='armada-manifest')
def _assert_missing_documents_raises(self, documents):
error_re = ('.*Documents must include at least one of each of .*')
error_re = (
'.*Documents must include at least one of each of .* and '
'only one .*')
self.assertRaisesRegexp(
exceptions.ManifestException, error_re, manifest.Manifest,
documents)
@ -374,11 +374,7 @@ class ManifestNegativeTestCase(testtools.TestCase):
def test_get_documents_missing_manifest(self):
# Validates exceptions.ManifestException is thrown if no manifest is
# found. Manifest is last document in sample YAML.
error_re = 'Documents must include at least one {}'.format(
schema.TYPE_MANIFEST)
self.assertRaisesRegexp(
exceptions.ManifestException, error_re, manifest.Manifest,
self.documents[:-1])
self._assert_missing_documents_raises(self.documents[:-1])
def test_get_documents_missing_charts(self):
# Validates exceptions.ManifestException is thrown if no chart is

View File

@ -1,53 +0,0 @@
Armada - Apply Chart
====================
Commands
--------
.. code:: bash
Usage: armada apply_chart [OPTIONS] [LOCATION]
This command installs and updates an Armada chart.
[LOCATION] must be a relative path to Armada Chart or a reference
to an Armada Chart kubernetes CR which has the same format, except as
noted in the :ref:`v2 document authoring documentation <document_authoring_v2>`.
To install or upgrade a chart, run:
$ armada apply_chart --release-prefix=armada my-chart.yaml
$ armada apply_chart --release-prefix=armada kube:armadacharts/my-namespace/my-chart
Options:
--release-prefix TEXT Release prefix to use. [required]
--disable-update-post Disable post-update Tiller operations.
--disable-update-pre Disable pre-update Tiller operations.
--metrics-output TEXT Output path for prometheus metric data, should
end in .prom. By default, no metric data is
output.
--tiller-host TEXT Tiller host IP.
--tiller-port INTEGER Tiller host port.
-tn, --tiller-namespace TEXT Tiller namespace.
--timeout INTEGER Specifies time to wait for each chart to fully
finish deploying.
--wait Force Tiller to wait until the chart is
deployed, rather than using the charts
specified wait policy. This is equivalent to
sequenced chartgroups.
--target-chart TEXT The target chart to deploy. Required for
specifying which chart to deploy when multiple
are available.
--bearer-token TEXT User Bearer token
--debug Enable debug logging.
--help Show this message and exit.
Synopsis
--------
The apply_chart command will deploy an armada chart definition, installing or
updating as appropriate.
``armada apply_chart --release-prefix=armada my-chart.yaml [--debug]``
``armada apply_chart --release-prefix=armada kube:armadacharts/my-namespace/my-chart [--debug]``

View File

@ -11,7 +11,6 @@ Commands Guide
:caption: Contents:
apply.rst
apply_chart.rst
rollback.rst
test.rst
tiller.rst

View File

@ -124,7 +124,6 @@ Chart
| dependencies | object | (optional) Override the `builtin chart dependencies`_ with a list of Chart documents |
| | | to use as dependencies instead. |
| | | NOTE: Builtin ".tgz" dependencies are not yet supported. |
| | | NOTE: This field is not supported in the ArmadaChart CRD. |
+-----------------+----------+---------------------------------------------------------------------------------------+
.. _wait_v2:
@ -155,8 +154,6 @@ Wait
| | | **array** - Lists all `Wait Resource`_ s to use, completely |
| | | overriding the default. Can be set to ``[]`` to disable all |
| | | resource types. |
| | | NOTE: To use the array form with the ArmadaChart CRD, the keyword |
| | | must be ``resources_list`` instead of ``resources``. |
| | | |
| | | See also `Wait Resources Examples`_. |
+-------------+----------+--------------------------------------------------------------------+

View File

@ -1,165 +0,0 @@
apiVersion: "apiextensions.k8s.io/v1"
kind: "CustomResourceDefinition"
metadata:
name: "armadacharts.armada.airshipit.org"
spec:
group: "armada.airshipit.org"
versions:
- name: v1alpha1
served: true
storage: true
schema:
openAPIV3Schema:
type: object
properties:
spec:
type: object
properties:
release:
type: string
namespace:
type: string
values:
type: object
x-kubernetes-preserve-unknown-fields: true
protected:
type: object
properties:
continue_processing:
type: boolean
test:
type: object
properties:
enabled:
type: boolean
timeout:
type: integer
options:
type: object
properties:
cleanup:
type: boolean
wait:
type: object
properties:
timeout:
type: integer
resources:
type: object
additionalProperties:
type: array
items:
type: object
properties:
labels:
type: object
additionalProperties:
type: string
min_ready:
x-kubernetes-int-or-string: true
anyOf:
- type: integer
- type: string
required:
type: boolean
resources_list:
type: array
items:
type: object
properties:
labels:
type: object
additionalProperties:
type: string
min_ready:
x-kubernetes-int-or-string: true
anyOf:
- type: integer
- type: string
required:
type: boolean
type:
type: string
required:
- type
labels:
type: object
additionalProperties:
type: string
native:
type: object
properties:
enabled:
type: boolean
# Note: This is specific to the kubernetes schema.
# Dynamically typed fields are disallowed by kubernetes
# structural schemas, so object and list resource overrides
# need two separate fields. We specify here that, exactly one
# of these can be given.
not:
allOf:
- required:
- resources
- required:
- resources_list
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:
pre:
type: object
properties:
delete:
type: array
items:
type: object
properties:
type:
type: string
labels:
type: object
additionalProperties:
type: string
required:
- type
options:
type: object
properties:
force:
type: boolean
recreate_pods:
type: boolean
no_hooks:
type: boolean
required:
- namespace
- release
- source
scope: "Namespaced"
names:
plural: "armadacharts"
singular: "armadachart"
kind: "ArmadaChart"

View File

@ -1,3 +0,0 @@
resources:
- chart-crd.yaml
- rbac.yaml

View File

@ -1,62 +0,0 @@
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: armada-controller
labels:
rbac.armada.airshipit.org/aggregate-to-armada: "true"
rules:
- apiGroups:
- "apps"
resources:
- deployments
- statefulsets
- daemonsets
verbs:
- get
- list
- watch
- apiGroups:
- batch
- extensions
resources:
- jobs
verbs:
- get
- list
- watch
- delete
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- delete
- apiGroups:
- apiextensions.k8s.io
resources:
- customresourcedefinitions
verbs:
- get
- create
- apiGroups:
- armada.process
resources:
- locks
verbs:
- get
- list
- create
- delete
- patch
- update
- apiGroups:
- armada.airshipit.org
resources:
- armadacharts
verbs:
- get
- list
---

View File

@ -1,28 +0,0 @@
#!/bin/bash
# Copyright 2020 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.
set -xe
CURRENT_DIR="$(pwd)"
: "${INSTALL_PATH:="../"}"
cd ${INSTALL_PATH}
: "${OSH_INFRA_COMMIT:="dc58ef9dddd0326cc86229eda4e21e269adb31be"}"
# Clone openstack-helm-infra
git clone https://opendev.org/openstack/openstack-helm-infra.git
cd openstack-helm-infra
git checkout "${OSH_INFRA_COMMIT}"
cd "${CURRENT_DIR}"

View File

@ -1,45 +0,0 @@
#!/bin/bash
# Copyright 2019, AT&T Intellectual Property
#
# 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.
set -xe
CURRENT_DIR="$(pwd)"
: "${OSH_INFRA_PATH:="../openstack-helm-infra"}"
# Configure proxy settings if $PROXY is set
if [ -n "${PROXY}" ]; then
. tools/deployment/airskiff/common/setup-proxy.sh
fi
# Deploy K8s with Minikube
cd "${OSH_INFRA_PATH}"
bash -c "./tools/deployment/common/005-deploy-k8s.sh"
# Add user to Docker group
# NOTE: This requires re-authentication. Restart your shell.
sudo adduser "$(whoami)" docker
sudo su - "$USER" -c bash <<'END_SCRIPT'
if echo $(groups) | grep -qv 'docker'; then
echo "You need to logout to apply group permissions"
echo "Please logout and login"
fi
END_SCRIPT
# clean up /etc/resolv.conf, if it includes a localhost dns address
sudo sed -i.bkp '/^nameserver.*127.0.0.1/d
w /dev/stdout' /etc/resolv.conf
cd "${CURRENT_DIR}"

View File

@ -1,20 +0,0 @@
#!/bin/bash
# Copyright 2020 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.
set -xe
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
./tools/airship2-integration/test/test.sh basic

View File

@ -1,24 +0,0 @@
apiVersion: "armada.airshipit.org/v1alpha1"
kind: "ArmadaChart"
metadata:
name: a1
namespace: test
spec:
release: a1
namespace: test
wait:
timeout: 100
labels:
release_group: armada-a1
source:
location: https://kubernetes-charts-incubator.storage.googleapis.com/raw-0.2.3.tgz
subpath: raw
type: tar
values:
resources:
- apiVersion: v1
kind: ConfigMap
metadata:
name: a1
data:
chart: a1

View File

@ -1,24 +0,0 @@
apiVersion: "armada.airshipit.org/v1alpha1"
kind: "ArmadaChart"
metadata:
name: a2
namespace: test
spec:
release: a2
namespace: test
wait:
timeout: 100
labels:
release_group: armada-a1
source:
location: https://kubernetes-charts-incubator.storage.googleapis.com/raw-0.2.3.tgz
subpath: raw
type: tar
values:
resources:
- apiVersion: v1
kind: ConfigMap
metadata:
name: a2
data:
chart: a2

View File

@ -1,24 +0,0 @@
apiVersion: "armada.airshipit.org/v1alpha1"
kind: "ArmadaChart"
metadata:
name: b1
namespace: test
spec:
release: b1
namespace: test
wait:
timeout: 100
labels:
release_group: armada-b1
source:
location: https://kubernetes-charts-incubator.storage.googleapis.com/raw-0.2.3.tgz
subpath: raw
type: tar
values:
resources:
- apiVersion: v1
kind: ConfigMap
metadata:
name: b1
data:
chart: b1

View File

@ -1,24 +0,0 @@
apiVersion: "armada.airshipit.org/v1alpha1"
kind: "ArmadaChart"
metadata:
name: b2
namespace: test
spec:
release: b2
namespace: test
wait:
timeout: 100
labels:
release_group: armada-b2
source:
location: https://kubernetes-charts-incubator.storage.googleapis.com/raw-0.2.3.tgz
subpath: raw
type: tar
values:
resources:
- apiVersion: v1
kind: ConfigMap
metadata:
name: b2
data:
chart: b2

View File

@ -1,24 +0,0 @@
apiVersion: "armada.airshipit.org/v1alpha1"
kind: "ArmadaChart"
metadata:
name: b3
namespace: test
spec:
release: b3
namespace: test
wait:
timeout: 100
labels:
release_group: armada-b3
source:
location: https://kubernetes-charts-incubator.storage.googleapis.com/raw-0.2.3.tgz
subpath: raw
type: tar
values:
resources:
- apiVersion: v1
kind: ConfigMap
metadata:
name: b3
data:
chart: b3

View File

@ -1,24 +0,0 @@
apiVersion: "armada.airshipit.org/v1alpha1"
kind: "ArmadaChart"
metadata:
name: c1
namespace: test
spec:
release: c1
namespace: test
wait:
timeout: 100
labels:
release_group: armada-c1
source:
location: https://kubernetes-charts-incubator.storage.googleapis.com/raw-0.2.3.tgz
subpath: raw
type: tar
values:
resources:
- apiVersion: v1
kind: ConfigMap
metadata:
name: c1
data:
chart: c1

View File

@ -1,51 +0,0 @@
# Copyright (c) 2020 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.
---
apiVersion: batch/v1
kind: Job
metadata:
namespace: "${NAMESPACE}"
name: "${JOB_NAME}"
spec:
backoffLimit: 0
template:
spec:
serviceAccountName: ${SERVICE_ACCOUNT}
restartPolicy: Never
containers:
- name: "test-airship2-integration"
image: "${IMAGE}"
imagePullPolicy: Never
volumeMounts:
- name: kube-config
mountPath: /armada/.kube/config
command:
- /bin/bash
- -c
- |-
set -xe
apply_chart() {
NAME=$1
armada apply_chart kube:armadacharts/$NAMESPACE/${DOLLAR}NAME --release-prefix ${RELEASE_PREFIX}
}
for CHART in ${CHARTS_SPACE_SEPARATED}; do
apply_chart ${DOLLAR}CHART
done
volumes:
- name: kube-config
hostPath:
path: "${KUBE_CONFIG}"
...

View File

@ -1,4 +0,0 @@
apiVersion: v1
kind: Namespace
metadata:
name: ${NAMESPACE}

View File

@ -1,18 +0,0 @@
apiVersion: v1
kind: ServiceAccount
metadata:
name: ${SERVICE_ACCOUNT}
namespace: ${NAMESPACE}
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: ${SERVICE_ACCOUNT}-armada-controller
subjects:
- kind: ServiceAccount
name: ${SERVICE_ACCOUNT}
namespace: ${NAMESPACE}
roleRef:
kind: ClusterRole
name: armada-controller
apiGroup: rbac.authorization.k8s.io

View File

@ -1,61 +0,0 @@
#!/bin/bash
# Copyright 2020 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.
set -xe
EXAMPLE=$1
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && pwd )"
export NAMESPACE=test
export SERVICE_ACCOUNT=test-armada
export KUBE_CONFIG=~/.kube/config
export RELEASE_PREFIX=test
export JOB_NAME=apply-chart-test
export IMAGE=quay.io/airshipit/armada:latest-ubuntu_bionic
TIMEOUT=300
# See https://stackoverflow.com/a/24964089
export DOLLAR="\$"
# Cleanup any previous runs
cleanup() {
kubectl delete namespace $NAMESPACE --ignore-not-found=true
for i in $(helm ls --short | grep $RELEASE_PREFIX-); do helm del --purge $i; done
}
cleanup
# Install namespace
envsubst < $DIR/test-namespace.yaml | kubectl apply -f -
# Install CRD
kubectl apply -k ./manifests
# Install RBAC
envsubst < $DIR/test-rbac.yaml | kubectl apply -f -
# Install example CRs
kubectl apply -R -f $DIR/examples/$EXAMPLE
# Run test
export CHARTS=$(kubectl get armadacharts -n $NAMESPACE -o name | cut -d / -f2)
export CHARTS_SPACE_SEPARATED=$(echo "$CHARTS" | tr "\n" " ")
envsubst < $DIR/test-job.yaml | kubectl create -f -
# Wait for test job completion
kubectl wait --timeout ${TIMEOUT}s --for=condition=Complete -n $NAMESPACE job/$JOB_NAME
POD_NAME=$(kubectl get pods -n $NAMESPACE -l job-name=$JOB_NAME -o json | jq -r '.items[0].metadata.name')
kubectl logs -n $NAMESPACE $POD_NAME
ACTUAL=$(helm ls --short)
EXPECTED=$(echo "$CHARTS" | sed -e "s/^/$RELEASE_PREFIX-/")
diff <(echo "$ACTUAL") <(echo "$EXPECTED")

View File

@ -1,45 +0,0 @@
# Copyright 2018 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.
- hosts: primary
tasks:
- name: Clone Required Repositories
shell: |
./tools/airship2-integration/000-clone-dependencies.sh
args:
chdir: "{{ zuul.project.src_dir }}"
- name: Deploy Kubernetes with Minikube
shell: |
./tools/airship2-integration/010-deploy-k8s.sh
args:
chdir: "{{ zuul.project.src_dir }}"
- name: Build Armada with submitted changes
shell: |
# Add image to minikube
eval $(minikube docker-env)
make images
args:
chdir: "{{ zuul.project.src_dir }}"
become: yes
- name: Apply charts
shell: |
mkdir ~/.kube
cp -rp /home/zuul/.kube/config ~/.kube/config
./tools/airship2-integration/020-apply-charts.sh
args:
chdir: "{{ zuul.project.src_dir }}"
become: yes