Application dirs and overrides updates
This commit includes the following changes to support updating versioned application: - helm application overrides are tied to a specific application - each application files are uploaded to its own versioned directory e.g. stx-openstack-1.0-13 app files will be located at, /opt/platform/armada/19.01/stx-openstack/1.0-13/... /opt/platform/helm/19.01/stx-openstack/1.0-13/... /scratch/apps/stx-openstack/1.0-13/... Story: 2005350 Task: 33439 Change-Id: I75555deda57181d069f24d458dda5bf08e7e17cc Signed-off-by: Angie Wang <angie.wang@windriver.com>
This commit is contained in:
parent
07587a049a
commit
b978111f19
|
@ -1,2 +1,2 @@
|
||||||
SRC_DIR="cgts-client"
|
SRC_DIR="cgts-client"
|
||||||
TIS_PATCH_VER=65
|
TIS_PATCH_VER=66
|
||||||
|
|
|
@ -7,6 +7,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from cgtsclient.common import base
|
from cgtsclient.common import base
|
||||||
|
from cgtsclient import exc
|
||||||
|
|
||||||
|
|
||||||
class App(base.Resource):
|
class App(base.Resource):
|
||||||
|
@ -66,3 +67,12 @@ class AppManager(base.Manager):
|
||||||
:param name: app_name
|
:param name: app_name
|
||||||
"""
|
"""
|
||||||
return self._delete(self._path(app_name))
|
return self._delete(self._path(app_name))
|
||||||
|
|
||||||
|
|
||||||
|
def _find_app(cc, app_name):
|
||||||
|
try:
|
||||||
|
app = cc.app.get(app_name)
|
||||||
|
except exc.HTTPNotFound:
|
||||||
|
raise exc.CommandError('Application not found: %s' % app_name)
|
||||||
|
else:
|
||||||
|
return app
|
||||||
|
|
|
@ -21,17 +21,18 @@ class HelmManager(base.Manager):
|
||||||
def _path(name=''):
|
def _path(name=''):
|
||||||
return '/v1/helm_charts/%s' % name
|
return '/v1/helm_charts/%s' % name
|
||||||
|
|
||||||
def list_charts(self):
|
def list_charts(self, app):
|
||||||
"""Get list of charts
|
"""Get list of charts
|
||||||
|
|
||||||
For each chart it will show any overrides for that chart along
|
For each chart it will show any overrides for that chart along
|
||||||
with the namespace of the overrides.
|
with the namespace of the overrides.
|
||||||
"""
|
"""
|
||||||
return self._list(self._path(), 'charts')
|
return self._list(self._path() + '?app_name=' + app, 'charts')
|
||||||
|
|
||||||
def get_overrides(self, name, namespace):
|
def get_overrides(self, app, name, namespace):
|
||||||
"""Get overrides for a given chart.
|
"""Get overrides for a given chart.
|
||||||
|
|
||||||
|
:param app_name: name of application
|
||||||
:param name: name of the chart
|
:param name: name of the chart
|
||||||
:param namespace: namespace for the chart overrides
|
:param namespace: namespace for the chart overrides
|
||||||
|
|
||||||
|
@ -39,14 +40,17 @@ class HelmManager(base.Manager):
|
||||||
specified chart.
|
specified chart.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
return self._list(self._path(name) + '?namespace=' + namespace)[0]
|
return self._list(self._path(app) +
|
||||||
|
'?name=' + name +
|
||||||
|
'&namespace=' + namespace)[0]
|
||||||
except IndexError:
|
except IndexError:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def update_overrides(self, name, namespace,
|
def update_overrides(self, app, name, namespace,
|
||||||
flag='reset', override_values={}):
|
flag='reset', override_values={}):
|
||||||
"""Update overrides for a given chart.
|
"""Update overrides for a given chart.
|
||||||
|
|
||||||
|
:param app_name: name of application
|
||||||
:param name: name of the chart
|
:param name: name of the chart
|
||||||
:param namespace: namespace for the chart overrides
|
:param namespace: namespace for the chart overrides
|
||||||
:param flag: 'reuse' or 'reset' to indicate how to handle existing
|
:param flag: 'reuse' or 'reset' to indicate how to handle existing
|
||||||
|
@ -56,12 +60,17 @@ class HelmManager(base.Manager):
|
||||||
This will return the end-user overrides for the specified chart.
|
This will return the end-user overrides for the specified chart.
|
||||||
"""
|
"""
|
||||||
body = {'flag': flag, 'values': override_values}
|
body = {'flag': flag, 'values': override_values}
|
||||||
return self._update(self._path(name) + '?namespace=' + namespace, body)
|
return self._update(self._path(app) +
|
||||||
|
'?name=' + name +
|
||||||
|
'&namespace=' + namespace, body)
|
||||||
|
|
||||||
def delete_overrides(self, name, namespace):
|
def delete_overrides(self, app, name, namespace):
|
||||||
"""Delete overrides for a given chart.
|
"""Delete overrides for a given chart.
|
||||||
|
|
||||||
|
:param app_name: name of application
|
||||||
:param name: name of the chart
|
:param name: name of the chart
|
||||||
:param namespace: namespace for the chart overrides
|
:param namespace: namespace for the chart overrides
|
||||||
"""
|
"""
|
||||||
return self._delete(self._path(name) + '?namespace=' + namespace)
|
return self._delete(self._path(app) +
|
||||||
|
'?name=' + name +
|
||||||
|
'&namespace=' + namespace)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import yaml
|
||||||
|
|
||||||
from cgtsclient.common import utils
|
from cgtsclient.common import utils
|
||||||
from cgtsclient import exc
|
from cgtsclient import exc
|
||||||
|
from cgtsclient.v1 import app as app_utils
|
||||||
|
|
||||||
|
|
||||||
def _print_helm_chart(chart):
|
def _print_helm_chart(chart):
|
||||||
|
@ -22,12 +23,32 @@ def _print_helm_chart(chart):
|
||||||
utils.print_dict(ordereddata)
|
utils.print_dict(ordereddata)
|
||||||
|
|
||||||
|
|
||||||
|
def _find_overrides(cc, app, chart, namespace):
|
||||||
|
charts = cc.helm.list_charts(app.name)
|
||||||
|
for c in charts:
|
||||||
|
if chart == c.name and namespace in c.namespaces:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
raise exc.CommandError('Chart overrides %s:%s for application '
|
||||||
|
'%s not found' %
|
||||||
|
(chart, namespace, app.name))
|
||||||
|
|
||||||
|
return c
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('app',
|
||||||
|
metavar='<app name>',
|
||||||
|
help="Name of the application")
|
||||||
def do_helm_override_list(cc, args):
|
def do_helm_override_list(cc, args):
|
||||||
"""List system helm charts."""
|
"""List system helm charts."""
|
||||||
charts = cc.helm.list_charts()
|
app = app_utils._find_app(cc, args.app)
|
||||||
|
charts = cc.helm.list_charts(app.name)
|
||||||
utils.print_list(charts, ['name', 'namespaces'], ['chart name', 'overrides namespaces'], sortby=0)
|
utils.print_list(charts, ['name', 'namespaces'], ['chart name', 'overrides namespaces'], sortby=0)
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('app',
|
||||||
|
metavar='<app name>',
|
||||||
|
help="Name of the application")
|
||||||
@utils.arg('chart', metavar='<chart name>',
|
@utils.arg('chart', metavar='<chart name>',
|
||||||
help="Name of chart")
|
help="Name of chart")
|
||||||
@utils.arg('namespace',
|
@utils.arg('namespace',
|
||||||
|
@ -35,14 +56,15 @@ def do_helm_override_list(cc, args):
|
||||||
help="namespace of chart overrides")
|
help="namespace of chart overrides")
|
||||||
def do_helm_override_show(cc, args):
|
def do_helm_override_show(cc, args):
|
||||||
"""Show overrides for chart."""
|
"""Show overrides for chart."""
|
||||||
try:
|
app = app_utils._find_app(cc, args.app)
|
||||||
chart = cc.helm.get_overrides(args.chart, args.namespace)
|
_find_overrides(cc, app, args.chart, args.namespace)
|
||||||
_print_helm_chart(chart)
|
chart = cc.helm.get_overrides(args.app, args.chart, args.namespace)
|
||||||
except exc.HTTPNotFound:
|
_print_helm_chart(chart)
|
||||||
raise exc.CommandError('chart overrides not found: %s:%s' % (
|
|
||||||
args.chart, args.namespace))
|
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('app',
|
||||||
|
metavar='<app name>',
|
||||||
|
help="Name of the application")
|
||||||
@utils.arg('chart',
|
@utils.arg('chart',
|
||||||
metavar='<chart name>',
|
metavar='<chart name>',
|
||||||
help="Name of chart")
|
help="Name of chart")
|
||||||
|
@ -51,15 +73,16 @@ def do_helm_override_show(cc, args):
|
||||||
help="namespace of chart overrides")
|
help="namespace of chart overrides")
|
||||||
def do_helm_override_delete(cc, args):
|
def do_helm_override_delete(cc, args):
|
||||||
"""Delete overrides for a chart."""
|
"""Delete overrides for a chart."""
|
||||||
try:
|
app = app_utils._find_app(cc, args.app)
|
||||||
cc.helm.delete_overrides(args.chart, args.namespace)
|
_find_overrides(cc, app, args.chart, args.namespace)
|
||||||
print('Deleted chart overrides for %s:%s' % (
|
cc.helm.delete_overrides(args.app, args.chart, args.namespace)
|
||||||
args.chart, args.namespace))
|
print('Deleted chart overrides %s:%s for application %s' %
|
||||||
except exc.HTTPNotFound:
|
(args.chart, args.namespace, args.app))
|
||||||
raise exc.CommandError('chart overrides not found: %s:%s' % (
|
|
||||||
args.chart, args.namespace))
|
|
||||||
|
|
||||||
|
|
||||||
|
@utils.arg('app',
|
||||||
|
metavar='<app name>',
|
||||||
|
help="Name of the application")
|
||||||
@utils.arg('chart',
|
@utils.arg('chart',
|
||||||
metavar='<chart name>',
|
metavar='<chart name>',
|
||||||
help="Name of chart")
|
help="Name of chart")
|
||||||
|
@ -85,6 +108,9 @@ def do_helm_override_delete(cc, args):
|
||||||
def do_helm_override_update(cc, args):
|
def do_helm_override_update(cc, args):
|
||||||
"""Update helm chart user overrides."""
|
"""Update helm chart user overrides."""
|
||||||
|
|
||||||
|
app = app_utils._find_app(cc, args.app)
|
||||||
|
_find_overrides(cc, app, args.chart, args.namespace)
|
||||||
|
|
||||||
# This logic results in similar behaviour to "helm upgrade".
|
# This logic results in similar behaviour to "helm upgrade".
|
||||||
flag = 'reset'
|
flag = 'reset'
|
||||||
if args.reuse_values and not args.reset_values:
|
if args.reuse_values and not args.reset_values:
|
||||||
|
@ -114,10 +140,6 @@ def do_helm_override_update(cc, args):
|
||||||
'set': override_set,
|
'set': override_set,
|
||||||
}
|
}
|
||||||
|
|
||||||
try:
|
chart = cc.helm.update_overrides(args.app, args.chart, args.namespace,
|
||||||
chart = cc.helm.update_overrides(args.chart, args.namespace,
|
flag, overrides)
|
||||||
flag, overrides)
|
|
||||||
except exc.HTTPNotFound:
|
|
||||||
raise exc.CommandError('helm chart not found: %s:%s' % (
|
|
||||||
args.chart, args.namespace))
|
|
||||||
_print_helm_chart(chart)
|
_print_helm_chart(chart)
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
SRC_DIR="sysinv"
|
SRC_DIR="sysinv"
|
||||||
TIS_PATCH_VER=318
|
TIS_PATCH_VER=319
|
||||||
|
|
|
@ -23,30 +23,28 @@ LOG = log.getLogger(__name__)
|
||||||
|
|
||||||
class HelmChartsController(rest.RestController):
|
class HelmChartsController(rest.RestController):
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(wtypes.text)
|
@wsme_pecan.wsexpose(wtypes.text, wtypes.text)
|
||||||
def get_all(self):
|
def get_all(self, app_name):
|
||||||
"""Provides information about the available charts to override."""
|
"""Provides information about the available charts to override."""
|
||||||
|
|
||||||
supported_apps = pecan.request.rpcapi.get_helm_applications(
|
try:
|
||||||
pecan.request.context)
|
objects.kube_app.get_by_name(
|
||||||
all_charts = {}
|
pecan.request.context, app_name)
|
||||||
for app in supported_apps:
|
except exception.KubeAppNotFound:
|
||||||
namespaces = pecan.request.rpcapi.get_helm_application_namespaces(
|
raise wsme.exc.ClientSideError(_("Application %s not found." % app_name))
|
||||||
pecan.request.context, app)
|
|
||||||
for chart in namespaces:
|
namespaces = pecan.request.rpcapi.get_helm_application_namespaces(
|
||||||
if chart not in all_charts:
|
pecan.request.context, app_name)
|
||||||
all_charts[chart] = namespaces[chart]
|
charts = [{'name': chart, 'namespaces': namespaces[chart]}
|
||||||
else:
|
for chart in namespaces]
|
||||||
all_charts[chart] = list(set().union(all_charts[chart],
|
|
||||||
namespaces[chart]))
|
|
||||||
|
|
||||||
charts = [{'name': c, 'namespaces': ns} for c, ns in all_charts.items()]
|
|
||||||
return {'charts': charts}
|
return {'charts': charts}
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text, wtypes.text)
|
@wsme_pecan.wsexpose(wtypes.text, wtypes.text, wtypes.text, wtypes.text)
|
||||||
def get_one(self, name, namespace):
|
def get_one(self, app_name, name, namespace):
|
||||||
"""Retrieve information about the given chart.
|
"""Retrieve information about the given chart.
|
||||||
|
|
||||||
|
:param app_name: name of application
|
||||||
:param name: name of helm chart
|
:param name: name of helm chart
|
||||||
:param namespace: namespace of chart overrides
|
:param namespace: namespace of chart overrides
|
||||||
"""
|
"""
|
||||||
|
@ -54,9 +52,13 @@ class HelmChartsController(rest.RestController):
|
||||||
|
|
||||||
# Get any user-specified overrides.
|
# Get any user-specified overrides.
|
||||||
try:
|
try:
|
||||||
db_chart = objects.helm_overrides.get_by_name(
|
app = objects.kube_app.get_by_name(
|
||||||
pecan.request.context, name, namespace)
|
pecan.request.context, app_name)
|
||||||
|
db_chart = objects.helm_overrides.get_by_appid_name(
|
||||||
|
pecan.request.context, app.id, name, namespace)
|
||||||
user_overrides = db_chart.user_overrides
|
user_overrides = db_chart.user_overrides
|
||||||
|
except exception.KubeAppNotFound:
|
||||||
|
raise wsme.exc.ClientSideError(_("Application %s not found." % app_name))
|
||||||
except exception.HelmOverrideNotFound:
|
except exception.HelmOverrideNotFound:
|
||||||
user_overrides = ''
|
user_overrides = ''
|
||||||
|
|
||||||
|
@ -92,10 +94,12 @@ class HelmChartsController(rest.RestController):
|
||||||
if not namespace:
|
if not namespace:
|
||||||
raise wsme.exc.ClientSideError(_("Namespace must be specified."))
|
raise wsme.exc.ClientSideError(_("Namespace must be specified."))
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(wtypes.text, wtypes.text, wtypes.text, wtypes.text, wtypes.text)
|
@wsme_pecan.wsexpose(wtypes.text, wtypes.text, wtypes.text,
|
||||||
def patch(self, name, namespace, flag, values):
|
wtypes.text, wtypes.text, wtypes.text)
|
||||||
|
def patch(self, app_name, name, namespace, flag, values):
|
||||||
""" Update user overrides.
|
""" Update user overrides.
|
||||||
|
|
||||||
|
:param app_name: name of application
|
||||||
:param name: chart name
|
:param name: chart name
|
||||||
:param namespace: namespace of chart overrides
|
:param namespace: namespace of chart overrides
|
||||||
:param flag: one of "reuse" or "reset", describes how to handle
|
:param flag: one of "reuse" or "reset", describes how to handle
|
||||||
|
@ -110,15 +114,20 @@ class HelmChartsController(rest.RestController):
|
||||||
# Get any stored user overrides for this chart. We'll need this
|
# Get any stored user overrides for this chart. We'll need this
|
||||||
# object later either way.
|
# object later either way.
|
||||||
try:
|
try:
|
||||||
db_chart = objects.helm_overrides.get_by_name(
|
app = objects.kube_app.get_by_name(
|
||||||
pecan.request.context, name, namespace)
|
pecan.request.context, app_name)
|
||||||
|
db_chart = objects.helm_overrides.get_by_appid_name(
|
||||||
|
pecan.request.context, app.id, name, namespace)
|
||||||
|
except exception.KubeAppNotFound:
|
||||||
|
raise wsme.exc.ClientSideError(_("Application %s not found." % app_name))
|
||||||
except exception.HelmOverrideNotFound:
|
except exception.HelmOverrideNotFound:
|
||||||
pecan.request.dbapi.helm_override_create({
|
pecan.request.dbapi.helm_override_create({
|
||||||
'name': name,
|
'name': name,
|
||||||
'namespace': namespace,
|
'namespace': namespace,
|
||||||
'user_overrides': ''})
|
'user_overrides': '',
|
||||||
db_chart = objects.helm_overrides.get_by_name(
|
'app_id': app.id})
|
||||||
pecan.request.context, name, namespace)
|
db_chart = objects.helm_overrides.get_by_appid_name(
|
||||||
|
pecan.request.context, app.id, name, namespace)
|
||||||
|
|
||||||
if flag == 'reuse':
|
if flag == 'reuse':
|
||||||
if db_chart.user_overrides is not None:
|
if db_chart.user_overrides is not None:
|
||||||
|
@ -150,16 +159,21 @@ class HelmChartsController(rest.RestController):
|
||||||
|
|
||||||
return chart
|
return chart
|
||||||
|
|
||||||
@wsme_pecan.wsexpose(None, wtypes.text, wtypes.text, status_code=204)
|
@wsme_pecan.wsexpose(None, wtypes.text, wtypes.text,
|
||||||
def delete(self, name, namespace):
|
wtypes.text, status_code=204)
|
||||||
|
def delete(self, app_name, name, namespace):
|
||||||
"""Delete user overrides for a chart
|
"""Delete user overrides for a chart
|
||||||
|
|
||||||
|
:param app_name: name of application
|
||||||
:param name: chart name.
|
:param name: chart name.
|
||||||
:param namespace: namespace of chart overrides
|
:param namespace: namespace of chart overrides
|
||||||
"""
|
"""
|
||||||
self.validate_name_and_namespace(name, namespace)
|
self.validate_name_and_namespace(name, namespace)
|
||||||
try:
|
try:
|
||||||
pecan.request.dbapi.helm_override_update(name, namespace,
|
app = objects.kube_app.get_by_name(pecan.request.context, app_name)
|
||||||
|
pecan.request.dbapi.helm_override_update(app.id, name, namespace,
|
||||||
{'user_overrides': None})
|
{'user_overrides': None})
|
||||||
|
except exception.KubeAppNotFound:
|
||||||
|
raise wsme.exc.ClientSideError(_("Application %s not found." % app_name))
|
||||||
except exception.HelmOverrideNotFound:
|
except exception.HelmOverrideNotFound:
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -22,14 +22,16 @@ CONF = cfg.CONF
|
||||||
|
|
||||||
def create_app_overrides_action(path, app_name=None, namespace=None):
|
def create_app_overrides_action(path, app_name=None, namespace=None):
|
||||||
dbapi = api.get_instance()
|
dbapi = api.get_instance()
|
||||||
operator = helm.HelmOperator(dbapi=dbapi, path=path)
|
operator = helm.HelmOperator(dbapi=dbapi)
|
||||||
operator.generate_helm_application_overrides(app_name, mode=None, cnamespace=namespace)
|
operator.generate_helm_application_overrides(path, app_name, mode=None,
|
||||||
|
cnamespace=namespace)
|
||||||
|
|
||||||
|
|
||||||
def create_armada_app_overrides_action(path, app_name=None, namespace=None):
|
def create_armada_app_overrides_action(path, app_name=None, namespace=None):
|
||||||
dbapi = api.get_instance()
|
dbapi = api.get_instance()
|
||||||
operator = helm.HelmOperator(dbapi=dbapi, path=path)
|
operator = helm.HelmOperator(dbapi=dbapi)
|
||||||
operator.generate_helm_application_overrides(app_name, mode=None, cnamespace=namespace,
|
operator.generate_helm_application_overrides(path, app_name, mode=None,
|
||||||
|
cnamespace=namespace,
|
||||||
armada_format=True,
|
armada_format=True,
|
||||||
armada_chart_info=None,
|
armada_chart_info=None,
|
||||||
combined=False)
|
combined=False)
|
||||||
|
@ -37,8 +39,8 @@ def create_armada_app_overrides_action(path, app_name=None, namespace=None):
|
||||||
|
|
||||||
def create_chart_override_action(path, chart_name=None, namespace=None):
|
def create_chart_override_action(path, chart_name=None, namespace=None):
|
||||||
dbapi = api.get_instance()
|
dbapi = api.get_instance()
|
||||||
operator = helm.HelmOperator(dbapi=dbapi, path=path)
|
operator = helm.HelmOperator(dbapi=dbapi)
|
||||||
operator.generate_helm_chart_overrides(chart_name, namespace)
|
operator.generate_helm_chart_overrides(path, chart_name, namespace)
|
||||||
|
|
||||||
|
|
||||||
def add_action_parsers(subparsers):
|
def add_action_parsers(subparsers):
|
||||||
|
|
|
@ -67,23 +67,30 @@ DOCKER_REGISTRY_SECRET = 'default-registry-key'
|
||||||
|
|
||||||
|
|
||||||
# Helper functions
|
# Helper functions
|
||||||
def generate_armada_manifest_filename(app_name, manifest_filename):
|
def generate_armada_manifest_filename(app_name, app_version, manifest_filename):
|
||||||
return os.path.join('/manifests', app_name + '-' + manifest_filename)
|
return os.path.join('/manifests', app_name, app_version,
|
||||||
|
|
||||||
|
|
||||||
def generate_armada_manifest_filename_abs(app_name, manifest_filename):
|
|
||||||
return os.path.join(constants.APP_SYNCED_DATA_PATH,
|
|
||||||
app_name + '-' + manifest_filename)
|
app_name + '-' + manifest_filename)
|
||||||
|
|
||||||
|
|
||||||
def generate_manifest_filename_abs(app_name, manifest_filename):
|
def generate_armada_manifest_dir(app_name, app_version):
|
||||||
|
return os.path.join(constants.APP_SYNCED_DATA_PATH, app_name, app_version)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_armada_manifest_filename_abs(armada_mfile_dir, app_name, manifest_filename):
|
||||||
|
return os.path.join(armada_mfile_dir, app_name + '-' + manifest_filename)
|
||||||
|
|
||||||
|
|
||||||
|
def generate_manifest_filename_abs(app_name, app_version, manifest_filename):
|
||||||
return os.path.join(constants.APP_INSTALL_PATH,
|
return os.path.join(constants.APP_INSTALL_PATH,
|
||||||
app_name, manifest_filename)
|
app_name, app_version, manifest_filename)
|
||||||
|
|
||||||
|
|
||||||
def generate_images_filename_abs(app_name):
|
def generate_images_filename_abs(armada_mfile_dir, app_name):
|
||||||
return os.path.join(constants.APP_SYNCED_DATA_PATH,
|
return os.path.join(armada_mfile_dir, app_name + '-images.yaml')
|
||||||
app_name + '-images.yaml')
|
|
||||||
|
|
||||||
|
def generate_overrides_dir(app_name, app_version):
|
||||||
|
return os.path.join(common.HELM_OVERRIDES_PATH, app_name, app_version)
|
||||||
|
|
||||||
|
|
||||||
def create_app_path(path):
|
def create_app_path(path):
|
||||||
|
@ -134,18 +141,20 @@ class AppOperator(object):
|
||||||
def _cleanup(self, app):
|
def _cleanup(self, app):
|
||||||
"""" Remove application directories and override files """
|
"""" Remove application directories and override files """
|
||||||
try:
|
try:
|
||||||
if app.system_app and app.status != constants.APP_UPLOAD_FAILURE:
|
if os.path.exists(app.overrides_dir):
|
||||||
self._remove_chart_overrides(app.armada_mfile_abs)
|
shutil.rmtree(os.path.dirname(
|
||||||
|
app.overrides_dir))
|
||||||
|
|
||||||
if os.path.exists(app.armada_mfile_abs):
|
if os.path.exists(app.armada_mfile_dir):
|
||||||
os.unlink(app.armada_mfile_abs)
|
shutil.rmtree(os.path.dirname(
|
||||||
if os.path.exists(app.imgfile_abs):
|
app.armada_mfile_dir))
|
||||||
os.unlink(app.imgfile_abs)
|
|
||||||
|
|
||||||
if os.path.exists(app.path):
|
if os.path.exists(app.path):
|
||||||
shutil.rmtree(app.path)
|
shutil.rmtree(os.path.dirname(
|
||||||
|
app.path))
|
||||||
except OSError as e:
|
except OSError as e:
|
||||||
LOG.error(e)
|
LOG.error(e)
|
||||||
|
raise
|
||||||
|
|
||||||
def _update_app_status(self, app, new_status=None, new_progress=None):
|
def _update_app_status(self, app, new_status=None, new_progress=None):
|
||||||
""" Persist new app status """
|
""" Persist new app status """
|
||||||
|
@ -244,10 +253,13 @@ class AppOperator(object):
|
||||||
orig_uid, orig_gid = get_app_install_root_path_ownership()
|
orig_uid, orig_gid = get_app_install_root_path_ownership()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# One time set up of Armada manifest path for the system
|
# One time set up of base armada manifest path for the system
|
||||||
if not os.path.isdir(constants.APP_SYNCED_DATA_PATH):
|
if not os.path.isdir(constants.APP_SYNCED_DATA_PATH):
|
||||||
os.makedirs(constants.APP_SYNCED_DATA_PATH)
|
os.makedirs(constants.APP_SYNCED_DATA_PATH)
|
||||||
|
|
||||||
|
if not os.path.isdir(app.armada_mfile_dir):
|
||||||
|
os.makedirs(app.armada_mfile_dir)
|
||||||
|
|
||||||
if not os.path.isdir(app.path):
|
if not os.path.isdir(app.path):
|
||||||
create_app_path(app.path)
|
create_app_path(app.path)
|
||||||
|
|
||||||
|
@ -307,7 +319,7 @@ class AppOperator(object):
|
||||||
image_tags.extend(ids)
|
image_tags.extend(ids)
|
||||||
return list(set(image_tags))
|
return list(set(image_tags))
|
||||||
|
|
||||||
def _get_image_tags_by_charts(self, app_images_file, app_manifest_file):
|
def _get_image_tags_by_charts(self, app_images_file, app_manifest_file, overrides_dir):
|
||||||
""" Mine the image tags for charts from the images file. Add the
|
""" Mine the image tags for charts from the images file. Add the
|
||||||
image tags to the manifest file if the image tags from the charts
|
image tags to the manifest file if the image tags from the charts
|
||||||
do not exist in both overrides file and manifest file. Convert
|
do not exist in both overrides file and manifest file. Convert
|
||||||
|
@ -349,7 +361,7 @@ class AppOperator(object):
|
||||||
|
|
||||||
# Get the image tags from the overrides file
|
# Get the image tags from the overrides file
|
||||||
overrides = chart_namespace + '-' + chart_name + '.yaml'
|
overrides = chart_namespace + '-' + chart_name + '.yaml'
|
||||||
app_overrides_file = os.path.join(common.HELM_OVERRIDES_PATH, overrides)
|
app_overrides_file = os.path.join(overrides_dir, overrides)
|
||||||
if os.path.exists(app_overrides_file):
|
if os.path.exists(app_overrides_file):
|
||||||
try:
|
try:
|
||||||
with open(app_overrides_file, 'r') as f:
|
with open(app_overrides_file, 'r') as f:
|
||||||
|
@ -443,12 +455,12 @@ class AppOperator(object):
|
||||||
LOG.info("Generating application overrides...")
|
LOG.info("Generating application overrides...")
|
||||||
app.charts = self._get_list_of_charts(app.armada_mfile_abs)
|
app.charts = self._get_list_of_charts(app.armada_mfile_abs)
|
||||||
self._helm.generate_helm_application_overrides(
|
self._helm.generate_helm_application_overrides(
|
||||||
app.name, mode=None, cnamespace=None, armada_format=True,
|
app.overrides_dir, app.name, mode=None, cnamespace=None,
|
||||||
armada_chart_info=app.charts, combined=True)
|
armada_format=True, armada_chart_info=app.charts, combined=True)
|
||||||
self._save_images_list_by_charts(app)
|
self._save_images_list_by_charts(app)
|
||||||
# Get the list of images from the updated images overrides
|
# Get the list of images from the updated images overrides
|
||||||
images_to_download = self._get_image_tags_by_charts(
|
images_to_download = self._get_image_tags_by_charts(
|
||||||
app.imgfile_abs, app.armada_mfile_abs)
|
app.imgfile_abs, app.armada_mfile_abs, app.overrides_dir)
|
||||||
else:
|
else:
|
||||||
# For custom apps, mine image tags from application path
|
# For custom apps, mine image tags from application path
|
||||||
images_to_download = self._get_image_tags_by_path(app.path)
|
images_to_download = self._get_image_tags_by_path(app.path)
|
||||||
|
@ -505,7 +517,7 @@ class AppOperator(object):
|
||||||
saved_images_list = self._retrieve_images_list(app.imgfile_abs)
|
saved_images_list = self._retrieve_images_list(app.imgfile_abs)
|
||||||
saved_download_images_list = list(saved_images_list.get("download_images"))
|
saved_download_images_list = list(saved_images_list.get("download_images"))
|
||||||
images_to_download = self._get_image_tags_by_charts(
|
images_to_download = self._get_image_tags_by_charts(
|
||||||
app.imgfile_abs, app.armada_mfile_abs)
|
app.imgfile_abs, app.armada_mfile_abs, app.overrides_dir)
|
||||||
if set(saved_download_images_list) != set(images_to_download):
|
if set(saved_download_images_list) != set(images_to_download):
|
||||||
saved_images_list.update({"download_images": images_to_download})
|
saved_images_list.update({"download_images": images_to_download})
|
||||||
with open(app.imgfile_abs, 'wb') as f:
|
with open(app.imgfile_abs, 'wb') as f:
|
||||||
|
@ -858,7 +870,7 @@ class AppOperator(object):
|
||||||
pass
|
pass
|
||||||
return charts
|
return charts
|
||||||
|
|
||||||
def _get_overrides_files(self, charts, app_name, mode):
|
def _get_overrides_files(self, overrides_dir, charts, app_name, mode):
|
||||||
"""Returns list of override files or None, used in
|
"""Returns list of override files or None, used in
|
||||||
application-install and application-delete."""
|
application-install and application-delete."""
|
||||||
|
|
||||||
|
@ -867,8 +879,7 @@ class AppOperator(object):
|
||||||
|
|
||||||
for chart in charts:
|
for chart in charts:
|
||||||
overrides = chart.namespace + '-' + chart.name + '.yaml'
|
overrides = chart.namespace + '-' + chart.name + '.yaml'
|
||||||
overrides_file = os.path.join(common.HELM_OVERRIDES_PATH,
|
overrides_file = os.path.join(overrides_dir, overrides)
|
||||||
overrides)
|
|
||||||
if not os.path.exists(overrides_file):
|
if not os.path.exists(overrides_file):
|
||||||
missing_overrides.append(overrides_file)
|
missing_overrides.append(overrides_file)
|
||||||
else:
|
else:
|
||||||
|
@ -881,8 +892,7 @@ class AppOperator(object):
|
||||||
chart.name, chart.namespace, app_name, mode):
|
chart.name, chart.namespace, app_name, mode):
|
||||||
overrides = chart.namespace + '-' + chart.name + \
|
overrides = chart.namespace + '-' + chart.name + \
|
||||||
'-meta' + '.yaml'
|
'-meta' + '.yaml'
|
||||||
overrides_file = os.path.join(common.HELM_OVERRIDES_PATH,
|
overrides_file = os.path.join(overrides_dir, overrides)
|
||||||
overrides)
|
|
||||||
if not os.path.exists(overrides_file):
|
if not os.path.exists(overrides_file):
|
||||||
missing_overrides.append(overrides_file)
|
missing_overrides.append(overrides_file)
|
||||||
else:
|
else:
|
||||||
|
@ -893,15 +903,17 @@ class AppOperator(object):
|
||||||
return None
|
return None
|
||||||
return available_overrides
|
return available_overrides
|
||||||
|
|
||||||
def _generate_armada_overrides_str(self, overrides_files):
|
def _generate_armada_overrides_str(self, app_name, app_version, overrides_files):
|
||||||
return " ".join([' --values /overrides/{0}'.format(os.path.basename(i))
|
return " ".join([' --values /overrides/{0}/{1}/{2}'.format(app_name, app_version,
|
||||||
|
os.path.basename(i))
|
||||||
for i in overrides_files])
|
for i in overrides_files])
|
||||||
|
|
||||||
def _remove_chart_overrides(self, manifest_file):
|
def _remove_chart_overrides(self, overrides_dir, manifest_file):
|
||||||
charts = self._get_list_of_charts(manifest_file)
|
charts = self._get_list_of_charts(manifest_file)
|
||||||
for chart in charts:
|
for chart in charts:
|
||||||
if chart.name in self._helm.chart_operators:
|
if chart.name in self._helm.chart_operators:
|
||||||
self._helm.remove_helm_chart_overrides(chart.name,
|
self._helm.remove_helm_chart_overrides(overrides_dir,
|
||||||
|
chart.name,
|
||||||
chart.namespace)
|
chart.namespace)
|
||||||
|
|
||||||
def _make_armada_request_with_monitor(self, app, request, overrides_str=None):
|
def _make_armada_request_with_monitor(self, app, request, overrides_str=None):
|
||||||
|
@ -1129,10 +1141,10 @@ class AppOperator(object):
|
||||||
self._upload_helm_charts(app)
|
self._upload_helm_charts(app)
|
||||||
|
|
||||||
self._save_images_list(app)
|
self._save_images_list(app)
|
||||||
self._update_app_status(app, constants.APP_UPLOAD_SUCCESS)
|
|
||||||
if app.patch_dependencies:
|
if app.patch_dependencies:
|
||||||
self._app._patch_report_app_dependencies(
|
self._app._patch_report_app_dependencies(
|
||||||
app.name, app.patch_dependencies)
|
app.name, app.patch_dependencies)
|
||||||
|
self._update_app_status(app, constants.APP_UPLOAD_SUCCESS)
|
||||||
LOG.info("Application (%s) upload completed." % app.name)
|
LOG.info("Application (%s) upload completed." % app.name)
|
||||||
except exception.KubeAppUploadFailure as e:
|
except exception.KubeAppUploadFailure as e:
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
|
@ -1182,16 +1194,19 @@ class AppOperator(object):
|
||||||
app, new_progress=constants.APP_PROGRESS_GENERATE_OVERRIDES)
|
app, new_progress=constants.APP_PROGRESS_GENERATE_OVERRIDES)
|
||||||
LOG.info("Generating application overrides...")
|
LOG.info("Generating application overrides...")
|
||||||
self._helm.generate_helm_application_overrides(
|
self._helm.generate_helm_application_overrides(
|
||||||
app.name, mode, cnamespace=None, armada_format=True,
|
app.overrides_dir, app.name, mode, cnamespace=None,
|
||||||
armada_chart_info=app.charts, combined=True)
|
armada_format=True, armada_chart_info=app.charts, combined=True)
|
||||||
overrides_files = self._get_overrides_files(app.charts, app.name, mode)
|
overrides_files = self._get_overrides_files(app.overrides_dir,
|
||||||
|
app.charts,
|
||||||
|
app.name, mode)
|
||||||
if overrides_files:
|
if overrides_files:
|
||||||
LOG.info("Application overrides generated.")
|
LOG.info("Application overrides generated.")
|
||||||
# Ensure all chart overrides are readable by Armada
|
# Ensure all chart overrides are readable by Armada
|
||||||
for file in overrides_files:
|
for file in overrides_files:
|
||||||
os.chmod(file, 0o644)
|
os.chmod(file, 0o644)
|
||||||
overrides_str =\
|
overrides_str =\
|
||||||
self._generate_armada_overrides_str(overrides_files)
|
self._generate_armada_overrides_str(app.name, app.version,
|
||||||
|
overrides_files)
|
||||||
self._update_app_status(
|
self._update_app_status(
|
||||||
app, new_progress=constants.APP_PROGRESS_DOWNLOAD_IMAGES)
|
app, new_progress=constants.APP_PROGRESS_DOWNLOAD_IMAGES)
|
||||||
self._download_images(app)
|
self._download_images(app)
|
||||||
|
@ -1321,22 +1336,33 @@ class AppOperator(object):
|
||||||
def __init__(self, rpc_app, is_system_app):
|
def __init__(self, rpc_app, is_system_app):
|
||||||
self._kube_app = rpc_app
|
self._kube_app = rpc_app
|
||||||
self.path = os.path.join(constants.APP_INSTALL_PATH,
|
self.path = os.path.join(constants.APP_INSTALL_PATH,
|
||||||
self._kube_app.get('name'))
|
self._kube_app.get('name'),
|
||||||
|
self._kube_app.get('app_version'))
|
||||||
self.charts_dir = os.path.join(self.path, 'charts')
|
self.charts_dir = os.path.join(self.path, 'charts')
|
||||||
self.images_dir = os.path.join(self.path, 'images')
|
self.images_dir = os.path.join(self.path, 'images')
|
||||||
self.tarfile = None
|
self.tarfile = None
|
||||||
self.downloaded_tarfile = False
|
self.downloaded_tarfile = False
|
||||||
self.system_app = is_system_app
|
self.system_app = is_system_app
|
||||||
|
self.overrides_dir = generate_overrides_dir(
|
||||||
|
self._kube_app.get('name'),
|
||||||
|
self._kube_app.get('app_version'))
|
||||||
|
self.armada_mfile_dir = generate_armada_manifest_dir(
|
||||||
|
self._kube_app.get('name'),
|
||||||
|
self._kube_app.get('app_version'))
|
||||||
self.armada_mfile = generate_armada_manifest_filename(
|
self.armada_mfile = generate_armada_manifest_filename(
|
||||||
self._kube_app.get('name'),
|
self._kube_app.get('name'),
|
||||||
|
self._kube_app.get('app_version'),
|
||||||
self._kube_app.get('manifest_file'))
|
self._kube_app.get('manifest_file'))
|
||||||
self.armada_mfile_abs = generate_armada_manifest_filename_abs(
|
self.armada_mfile_abs = generate_armada_manifest_filename_abs(
|
||||||
|
self.armada_mfile_dir,
|
||||||
self._kube_app.get('name'),
|
self._kube_app.get('name'),
|
||||||
self._kube_app.get('manifest_file'))
|
self._kube_app.get('manifest_file'))
|
||||||
self.mfile_abs = generate_manifest_filename_abs(
|
self.mfile_abs = generate_manifest_filename_abs(
|
||||||
self._kube_app.get('name'),
|
self._kube_app.get('name'),
|
||||||
|
self._kube_app.get('app_version'),
|
||||||
self._kube_app.get('manifest_file'))
|
self._kube_app.get('manifest_file'))
|
||||||
self.imgfile_abs = generate_images_filename_abs(
|
self.imgfile_abs = generate_images_filename_abs(
|
||||||
|
self.armada_mfile_dir,
|
||||||
self._kube_app.get('name'))
|
self._kube_app.get('name'))
|
||||||
|
|
||||||
self.patch_dependencies = []
|
self.patch_dependencies = []
|
||||||
|
@ -1379,25 +1405,35 @@ class AppOperator(object):
|
||||||
self._kube_app.manifest_name = new_mname
|
self._kube_app.manifest_name = new_mname
|
||||||
self._kube_app.manifest_file = new_mfile
|
self._kube_app.manifest_file = new_mfile
|
||||||
self.armada_mfile = generate_armada_manifest_filename(
|
self.armada_mfile = generate_armada_manifest_filename(
|
||||||
self.name, new_mfile)
|
self.name, self.version, new_mfile)
|
||||||
self.armada_mfile_abs = generate_armada_manifest_filename_abs(
|
self.armada_mfile_abs = generate_armada_manifest_filename_abs(
|
||||||
self.name, new_mfile)
|
self.armada_mfile_dir, self.name, new_mfile)
|
||||||
self.mfile_abs = generate_manifest_filename_abs(
|
self.mfile_abs = generate_manifest_filename_abs(
|
||||||
self.name, new_mfile)
|
self.name, self.version, new_mfile)
|
||||||
|
|
||||||
def regenerate_application_info(self, new_name, new_version, new_patch_dependencies):
|
def regenerate_application_info(self, new_name, new_version, new_patch_dependencies):
|
||||||
self._kube_app.name = new_name
|
self._kube_app.name = new_name
|
||||||
self._kube_app.app_version = new_version
|
self._kube_app.app_version = new_version
|
||||||
self.system_app = \
|
self.system_app = \
|
||||||
(self.name == constants.HELM_APP_OPENSTACK)
|
(self.name == constants.HELM_APP_OPENSTACK)
|
||||||
self.imgfile_abs = \
|
|
||||||
generate_images_filename_abs(self.name)
|
new_armada_dir = generate_armada_manifest_dir(
|
||||||
|
self.name, self.version)
|
||||||
|
shutil.move(self.armada_mfile_dir, new_armada_dir)
|
||||||
|
shutil.rmtree(os.path.dirname(self.armada_mfile_dir))
|
||||||
|
self.armada_mfile_dir = new_armada_dir
|
||||||
|
|
||||||
new_path = os.path.join(
|
new_path = os.path.join(
|
||||||
constants.APP_INSTALL_PATH, self.name)
|
constants.APP_INSTALL_PATH, self.name, self.version)
|
||||||
os.rename(self.path, new_path)
|
shutil.move(self.path, new_path)
|
||||||
|
shutil.rmtree(os.path.dirname(self.path))
|
||||||
self.path = new_path
|
self.path = new_path
|
||||||
|
|
||||||
self.charts_dir = os.path.join(self.path, 'charts')
|
self.charts_dir = os.path.join(self.path, 'charts')
|
||||||
self.images_dir = os.path.join(self.path, 'images')
|
self.images_dir = os.path.join(self.path, 'images')
|
||||||
|
self.imgfile_abs = \
|
||||||
|
generate_images_filename_abs(self.armada_mfile_dir, self.name)
|
||||||
|
self.overrides_dir = generate_overrides_dir(self.name, self.version)
|
||||||
self.patch_dependencies = new_patch_dependencies
|
self.patch_dependencies = new_patch_dependencies
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7358,9 +7358,10 @@ class Connection(api.Connection):
|
||||||
raise exception.CertificateNotFound(uuid)
|
raise exception.CertificateNotFound(uuid)
|
||||||
query.delete()
|
query.delete()
|
||||||
|
|
||||||
def _helm_override_get(self, name, namespace):
|
def _helm_override_get(self, app_id, name, namespace):
|
||||||
query = model_query(models.HelmOverrides)
|
query = model_query(models.HelmOverrides)
|
||||||
query = query.filter_by(name=name, namespace=namespace)
|
query = query.filter_by(
|
||||||
|
app_id=app_id, name=name, namespace=namespace)
|
||||||
try:
|
try:
|
||||||
return query.one()
|
return query.one()
|
||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
|
@ -7382,12 +7383,13 @@ class Connection(api.Connection):
|
||||||
(values['name']))
|
(values['name']))
|
||||||
raise exception.HelmOverrideAlreadyExists(
|
raise exception.HelmOverrideAlreadyExists(
|
||||||
name=values['name'], namespace=values['namespace'])
|
name=values['name'], namespace=values['namespace'])
|
||||||
return self._helm_override_get(values['name'],
|
return self._helm_override_get(values['app_id'],
|
||||||
|
values['name'],
|
||||||
values['namespace'])
|
values['namespace'])
|
||||||
|
|
||||||
@objects.objectify(objects.helm_overrides)
|
@objects.objectify(objects.helm_overrides)
|
||||||
def helm_override_get(self, name, namespace):
|
def helm_override_get(self, app_id, name, namespace):
|
||||||
return self._helm_override_get(name, namespace)
|
return self._helm_override_get(app_id, name, namespace)
|
||||||
|
|
||||||
@objects.objectify(objects.helm_overrides)
|
@objects.objectify(objects.helm_overrides)
|
||||||
def helm_override_get_all(self):
|
def helm_override_get_all(self):
|
||||||
|
@ -7395,10 +7397,11 @@ class Connection(api.Connection):
|
||||||
return query.all()
|
return query.all()
|
||||||
|
|
||||||
@objects.objectify(objects.helm_overrides)
|
@objects.objectify(objects.helm_overrides)
|
||||||
def helm_override_update(self, name, namespace, values):
|
def helm_override_update(self, app_id, name, namespace, values):
|
||||||
with _session_for_write() as session:
|
with _session_for_write() as session:
|
||||||
query = model_query(models.HelmOverrides, session=session)
|
query = model_query(models.HelmOverrides, session=session)
|
||||||
query = query.filter_by(name=name, namespace=namespace)
|
query = query.filter_by(
|
||||||
|
app_id=app_id, name=name, namespace=namespace)
|
||||||
|
|
||||||
count = query.update(values, synchronize_session='fetch')
|
count = query.update(values, synchronize_session='fetch')
|
||||||
if count == 0:
|
if count == 0:
|
||||||
|
@ -7406,10 +7409,11 @@ class Connection(api.Connection):
|
||||||
namespace=namespace)
|
namespace=namespace)
|
||||||
return query.one()
|
return query.one()
|
||||||
|
|
||||||
def helm_override_destroy(self, name, namespace):
|
def helm_override_destroy(self, app_id, name, namespace):
|
||||||
with _session_for_write() as session:
|
with _session_for_write() as session:
|
||||||
query = model_query(models.HelmOverrides, session=session)
|
query = model_query(models.HelmOverrides, session=session)
|
||||||
query = query.filter_by(name=name, namespace=namespace)
|
query = query.filter_by(
|
||||||
|
app_id=app_id, name=name, namespace=namespace)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
query.one()
|
query.one()
|
||||||
|
@ -7573,6 +7577,7 @@ class Connection(api.Connection):
|
||||||
"operation is not allowed while status is " + app.status
|
"operation is not allowed while status is " + app.status
|
||||||
raise exception.KubeAppDeleteFailure(
|
raise exception.KubeAppDeleteFailure(
|
||||||
name=name,
|
name=name,
|
||||||
|
version=app.app_version,
|
||||||
reason=failure_reason)
|
reason=failure_reason)
|
||||||
except NoResultFound:
|
except NoResultFound:
|
||||||
raise exception.KubeAppNotFound(name)
|
raise exception.KubeAppNotFound(name)
|
||||||
|
|
|
@ -25,7 +25,7 @@ def upgrade(migrate_engine):
|
||||||
meta = MetaData()
|
meta = MetaData()
|
||||||
meta.bind = migrate_engine
|
meta.bind = migrate_engine
|
||||||
|
|
||||||
# Define and create the helm_overrides table.
|
# Define and create the kube_app table.
|
||||||
kube_app = Table(
|
kube_app = Table(
|
||||||
'kube_app',
|
'kube_app',
|
||||||
meta,
|
meta,
|
|
@ -6,7 +6,7 @@
|
||||||
#
|
#
|
||||||
|
|
||||||
from sqlalchemy import DateTime, String, Text, Integer
|
from sqlalchemy import DateTime, String, Text, Integer
|
||||||
from sqlalchemy import Column, MetaData, Table, UniqueConstraint
|
from sqlalchemy import Column, MetaData, Table, UniqueConstraint, ForeignKey
|
||||||
|
|
||||||
from sysinv.openstack.common import log
|
from sysinv.openstack.common import log
|
||||||
|
|
||||||
|
@ -25,6 +25,8 @@ def upgrade(migrate_engine):
|
||||||
meta = MetaData()
|
meta = MetaData()
|
||||||
meta.bind = migrate_engine
|
meta.bind = migrate_engine
|
||||||
|
|
||||||
|
Table('kube_app', meta, autoload=True)
|
||||||
|
|
||||||
# Define and create the helm_overrides table.
|
# Define and create the helm_overrides table.
|
||||||
helm_overrides = Table(
|
helm_overrides = Table(
|
||||||
'helm_overrides',
|
'helm_overrides',
|
||||||
|
@ -36,7 +38,9 @@ def upgrade(migrate_engine):
|
||||||
Column('name', String(255), nullable=False),
|
Column('name', String(255), nullable=False),
|
||||||
Column('namespace', String(255), nullable=False),
|
Column('namespace', String(255), nullable=False),
|
||||||
Column('user_overrides', Text, nullable=True),
|
Column('user_overrides', Text, nullable=True),
|
||||||
UniqueConstraint('name', 'namespace', name='u_name_namespace'),
|
Column('app_id', Integer,
|
||||||
|
ForeignKey('kube_app.id', ondelete='CASCADE')),
|
||||||
|
UniqueConstraint('name', 'namespace', 'app_id', name='u_app_name_namespace'),
|
||||||
|
|
||||||
mysql_engine=ENGINE,
|
mysql_engine=ENGINE,
|
||||||
mysql_charset=CHARSET,
|
mysql_charset=CHARSET,
|
|
@ -1677,7 +1677,9 @@ class HelmOverrides(Base):
|
||||||
namespace = Column(String(255), nullable=False)
|
namespace = Column(String(255), nullable=False)
|
||||||
user_overrides = Column(Text, nullable=True)
|
user_overrides = Column(Text, nullable=True)
|
||||||
system_overrides = Column(JSONEncodedDict, nullable=True)
|
system_overrides = Column(JSONEncodedDict, nullable=True)
|
||||||
UniqueConstraint('name', 'namespace', name='u_name_namespace')
|
app_id = Column(Integer, ForeignKey('kube_app.id', ondelete='CASCADE'))
|
||||||
|
kube_app = relationship("KubeApp", lazy="joined", join_depth=1)
|
||||||
|
UniqueConstraint('name', 'namespace', 'app_id', name='u_app_name_namespace')
|
||||||
|
|
||||||
|
|
||||||
class Label(Base):
|
class Label(Base):
|
||||||
|
|
|
@ -45,12 +45,8 @@ def helm_context(func):
|
||||||
class HelmOperator(object):
|
class HelmOperator(object):
|
||||||
"""Class to encapsulate helm override operations for System Inventory"""
|
"""Class to encapsulate helm override operations for System Inventory"""
|
||||||
|
|
||||||
def __init__(self, dbapi=None, path=None):
|
def __init__(self, dbapi=None):
|
||||||
if path is None:
|
|
||||||
path = common.HELM_OVERRIDES_PATH
|
|
||||||
|
|
||||||
self.dbapi = dbapi
|
self.dbapi = dbapi
|
||||||
self.path = path
|
|
||||||
|
|
||||||
# register chart operators for lookup
|
# register chart operators for lookup
|
||||||
self.chart_operators = {}
|
self.chart_operators = {}
|
||||||
|
@ -377,7 +373,7 @@ class HelmOperator(object):
|
||||||
return values
|
return values
|
||||||
|
|
||||||
@helm_context
|
@helm_context
|
||||||
def generate_helm_chart_overrides(self, chart_name, cnamespace=None):
|
def generate_helm_chart_overrides(self, path, chart_name, cnamespace=None):
|
||||||
"""Generate system helm chart overrides
|
"""Generate system helm chart overrides
|
||||||
|
|
||||||
This method will generate system helm chart override an write them to a
|
This method will generate system helm chart override an write them to a
|
||||||
|
@ -399,7 +395,8 @@ class HelmOperator(object):
|
||||||
overrides = self._get_helm_chart_overrides(
|
overrides = self._get_helm_chart_overrides(
|
||||||
chart_name,
|
chart_name,
|
||||||
cnamespace)
|
cnamespace)
|
||||||
self._write_chart_overrides(chart_name,
|
self._write_chart_overrides(path,
|
||||||
|
chart_name,
|
||||||
cnamespace,
|
cnamespace,
|
||||||
overrides)
|
overrides)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -424,7 +421,8 @@ class HelmOperator(object):
|
||||||
return overrides
|
return overrides
|
||||||
|
|
||||||
@helm_context
|
@helm_context
|
||||||
def generate_helm_application_overrides(self, app_name, mode=None,
|
def generate_helm_application_overrides(self, path, app_name,
|
||||||
|
mode=None,
|
||||||
cnamespace=None,
|
cnamespace=None,
|
||||||
armada_format=False,
|
armada_format=False,
|
||||||
armada_chart_info=None,
|
armada_chart_info=None,
|
||||||
|
@ -450,6 +448,11 @@ class HelmOperator(object):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if app_name in self.helm_applications:
|
if app_name in self.helm_applications:
|
||||||
|
try:
|
||||||
|
app = self.dbapi.kube_app_get(app_name)
|
||||||
|
except exception.KubeAppNotFound:
|
||||||
|
LOG.exception("Application %s not found." % app_name)
|
||||||
|
|
||||||
app_overrides = self._get_helm_application_overrides(app_name,
|
app_overrides = self._get_helm_application_overrides(app_name,
|
||||||
cnamespace)
|
cnamespace)
|
||||||
for (chart_name, overrides) in iteritems(app_overrides):
|
for (chart_name, overrides) in iteritems(app_overrides):
|
||||||
|
@ -468,7 +471,7 @@ class HelmOperator(object):
|
||||||
for chart_namespace in overrides.keys():
|
for chart_namespace in overrides.keys():
|
||||||
try:
|
try:
|
||||||
db_chart = self.dbapi.helm_override_get(
|
db_chart = self.dbapi.helm_override_get(
|
||||||
chart_name, chart_namespace)
|
app.id, chart_name, chart_namespace)
|
||||||
db_user_overrides = db_chart.user_overrides
|
db_user_overrides = db_chart.user_overrides
|
||||||
if db_user_overrides:
|
if db_user_overrides:
|
||||||
file_overrides.append(yaml.dump(
|
file_overrides.append(yaml.dump(
|
||||||
|
@ -495,7 +498,7 @@ class HelmOperator(object):
|
||||||
chart_name, armada_chart_repo_name,
|
chart_name, armada_chart_repo_name,
|
||||||
key, overrides[key])
|
key, overrides[key])
|
||||||
overrides[key] = new_overrides
|
overrides[key] = new_overrides
|
||||||
self._write_chart_overrides(chart_name, cnamespace, overrides)
|
self._write_chart_overrides(path, chart_name, cnamespace, overrides)
|
||||||
|
|
||||||
# Write any meta-overrides for this chart. These will be in
|
# Write any meta-overrides for this chart. These will be in
|
||||||
# armada format already.
|
# armada format already.
|
||||||
|
@ -507,14 +510,14 @@ class HelmOperator(object):
|
||||||
if overrides:
|
if overrides:
|
||||||
chart_meta_name = chart_name + '-meta'
|
chart_meta_name = chart_name + '-meta'
|
||||||
self._write_chart_overrides(
|
self._write_chart_overrides(
|
||||||
chart_meta_name, cnamespace, overrides)
|
path, chart_meta_name, cnamespace, overrides)
|
||||||
|
|
||||||
elif app_name:
|
elif app_name:
|
||||||
LOG.exception("%s application is not supported" % app_name)
|
LOG.exception("%s application is not supported" % app_name)
|
||||||
else:
|
else:
|
||||||
LOG.exception("application name is required")
|
LOG.exception("application name is required")
|
||||||
|
|
||||||
def remove_helm_chart_overrides(self, chart_name, cnamespace=None):
|
def remove_helm_chart_overrides(self, path, chart_name, cnamespace=None):
|
||||||
"""Remove the overrides files for a chart"""
|
"""Remove the overrides files for a chart"""
|
||||||
|
|
||||||
if chart_name in self.chart_operators:
|
if chart_name in self.chart_operators:
|
||||||
|
@ -529,7 +532,7 @@ class HelmOperator(object):
|
||||||
|
|
||||||
for f in filenames:
|
for f in filenames:
|
||||||
try:
|
try:
|
||||||
self._remove_overrides(f)
|
self._remove_overrides(path, f)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception("failed to remove %s overrides: %s: %s" % (
|
LOG.exception("failed to remove %s overrides: %s: %s" % (
|
||||||
chart_name, f, e))
|
chart_name, f, e))
|
||||||
|
@ -537,12 +540,12 @@ class HelmOperator(object):
|
||||||
LOG.exception("chart %s not supported for system overrides" %
|
LOG.exception("chart %s not supported for system overrides" %
|
||||||
chart_name)
|
chart_name)
|
||||||
|
|
||||||
def _write_chart_overrides(self, chart_name, cnamespace, overrides):
|
def _write_chart_overrides(self, path, chart_name, cnamespace, overrides):
|
||||||
"""Write a one or more overrides files for a chart. """
|
"""Write a one or more overrides files for a chart. """
|
||||||
|
|
||||||
def _write_file(filename, values):
|
def _write_file(filename, values):
|
||||||
try:
|
try:
|
||||||
self._write_overrides(filename, values)
|
self._write_overrides(path, filename, values)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception("failed to write %s overrides: %s: %s" % (
|
LOG.exception("failed to write %s overrides: %s: %s" % (
|
||||||
chart_name, filename, e))
|
chart_name, filename, e))
|
||||||
|
@ -553,12 +556,15 @@ class HelmOperator(object):
|
||||||
for ns in overrides.keys():
|
for ns in overrides.keys():
|
||||||
_write_file("%s-%s.yaml" % (ns, chart_name), overrides[ns])
|
_write_file("%s-%s.yaml" % (ns, chart_name), overrides[ns])
|
||||||
|
|
||||||
def _write_overrides(self, filename, overrides):
|
def _write_overrides(self, path, filename, overrides):
|
||||||
"""Write a single overrides file. """
|
"""Write a single overrides file. """
|
||||||
|
|
||||||
filepath = os.path.join(self.path, filename)
|
if not os.path.isdir(path):
|
||||||
|
os.makedirs(path)
|
||||||
|
|
||||||
|
filepath = os.path.join(path, filename)
|
||||||
try:
|
try:
|
||||||
fd, tmppath = tempfile.mkstemp(dir=self.path, prefix=filename,
|
fd, tmppath = tempfile.mkstemp(dir=path, prefix=filename,
|
||||||
text=True)
|
text=True)
|
||||||
|
|
||||||
with open(tmppath, 'w') as f:
|
with open(tmppath, 'w') as f:
|
||||||
|
@ -569,10 +575,10 @@ class HelmOperator(object):
|
||||||
LOG.exception("failed to write overrides file: %s" % filepath)
|
LOG.exception("failed to write overrides file: %s" % filepath)
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def _remove_overrides(self, filename):
|
def _remove_overrides(self, path, filename):
|
||||||
"""Remove a single overrides file. """
|
"""Remove a single overrides file. """
|
||||||
|
|
||||||
filepath = os.path.join(self.path, filename)
|
filepath = os.path.join(path, filename)
|
||||||
try:
|
try:
|
||||||
if os.path.exists(filepath):
|
if os.path.exists(filepath):
|
||||||
os.unlink(filepath)
|
os.unlink(filepath)
|
||||||
|
|
|
@ -149,7 +149,9 @@ class OpenstackBaseHelm(base.BaseHelm):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
try:
|
try:
|
||||||
override = self.dbapi.helm_override_get(name=chart,
|
app = self.dbapi.kube_app_get(constants.HELM_APP_OPENSTACK)
|
||||||
|
override = self.dbapi.helm_override_get(app_id=app.id,
|
||||||
|
name=chart,
|
||||||
namespace=namespace)
|
namespace=namespace)
|
||||||
except exception.HelmOverrideNotFound:
|
except exception.HelmOverrideNotFound:
|
||||||
# Override for this chart not found, so create one
|
# Override for this chart not found, so create one
|
||||||
|
@ -157,6 +159,7 @@ class OpenstackBaseHelm(base.BaseHelm):
|
||||||
values = {
|
values = {
|
||||||
'name': chart,
|
'name': chart,
|
||||||
'namespace': namespace,
|
'namespace': namespace,
|
||||||
|
'app_id': app.id,
|
||||||
}
|
}
|
||||||
override = self.dbapi.helm_override_create(values=values)
|
override = self.dbapi.helm_override_create(values=values)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -176,7 +179,7 @@ class OpenstackBaseHelm(base.BaseHelm):
|
||||||
})
|
})
|
||||||
try:
|
try:
|
||||||
self.dbapi.helm_override_update(
|
self.dbapi.helm_override_update(
|
||||||
name=chart, namespace=namespace, values=values)
|
app_id=app.id, name=chart, namespace=namespace, values=values)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
LOG.exception(e)
|
LOG.exception(e)
|
||||||
|
|
||||||
|
@ -337,13 +340,16 @@ class OpenstackBaseHelm(base.BaseHelm):
|
||||||
|
|
||||||
def _get_or_generate_ssh_keys(self, chart, namespace):
|
def _get_or_generate_ssh_keys(self, chart, namespace):
|
||||||
try:
|
try:
|
||||||
override = self.dbapi.helm_override_get(name=chart,
|
app = self.dbapi.kube_app_get(constants.HELM_APP_OPENSTACK)
|
||||||
|
override = self.dbapi.helm_override_get(app_id=app.id,
|
||||||
|
name=chart,
|
||||||
namespace=namespace)
|
namespace=namespace)
|
||||||
except exception.HelmOverrideNotFound:
|
except exception.HelmOverrideNotFound:
|
||||||
# Override for this chart not found, so create one
|
# Override for this chart not found, so create one
|
||||||
values = {
|
values = {
|
||||||
'name': chart,
|
'name': chart,
|
||||||
'namespace': namespace,
|
'namespace': namespace,
|
||||||
|
'app_id': app.id
|
||||||
}
|
}
|
||||||
override = self.dbapi.helm_override_create(values=values)
|
override = self.dbapi.helm_override_create(values=values)
|
||||||
|
|
||||||
|
@ -362,7 +368,7 @@ class OpenstackBaseHelm(base.BaseHelm):
|
||||||
values['system_overrides'].update({'privatekey': newprivatekey,
|
values['system_overrides'].update({'privatekey': newprivatekey,
|
||||||
'publickey': newpublickey})
|
'publickey': newpublickey})
|
||||||
self.dbapi.helm_override_update(
|
self.dbapi.helm_override_update(
|
||||||
name=chart, namespace=namespace, values=values)
|
app_id=app.id, name=chart, namespace=namespace, values=values)
|
||||||
|
|
||||||
return newprivatekey, newpublickey
|
return newprivatekey, newpublickey
|
||||||
|
|
||||||
|
|
|
@ -21,11 +21,13 @@ class HelmOverrides(base.SysinvObject):
|
||||||
'namespace': utils.str_or_none,
|
'namespace': utils.str_or_none,
|
||||||
'user_overrides': utils.str_or_none,
|
'user_overrides': utils.str_or_none,
|
||||||
'system_overrides': utils.dict_or_none,
|
'system_overrides': utils.dict_or_none,
|
||||||
|
'app_id': int
|
||||||
}
|
}
|
||||||
|
|
||||||
@base.remotable_classmethod
|
@base.remotable_classmethod
|
||||||
def get_by_name(cls, context, name, namespace):
|
def get_by_appid_name(cls, context, app_id, name, namespace):
|
||||||
return cls.dbapi.helm_override_get(name, namespace)
|
return cls.dbapi.helm_override_get(app_id, name, namespace)
|
||||||
|
|
||||||
def save_changes(self, context, updates):
|
def save_changes(self, context, updates):
|
||||||
self.dbapi.helm_override_update(self.name, self.namespace, updates)
|
self.dbapi.helm_override_update(self.app_id, self.name,
|
||||||
|
self.namespace, updates)
|
||||||
|
|
Loading…
Reference in New Issue