[feature] adding-pre-post-actions-to-yaml (#44)

* fix multiple release items
* remove old configs in kubernetes
* add skip flags
This commit is contained in:
Alexis Rivera DeLa Torre 2017-04-17 14:24:30 -05:00 committed by Alan Meadows
parent 6355fee383
commit e4f49e9f8a
7 changed files with 171 additions and 26 deletions

1
.gitignore vendored
View File

@ -87,3 +87,4 @@ ENV/
# Rope project settings
.ropeproject

View File

@ -49,6 +49,8 @@ class Armada(object):
chart = dotify(entry['chart'])
values = entry['chart']['values']
pre_actions = {}
post_actions = {}
if chart.release_name is None:
continue
@ -61,16 +63,23 @@ class Armada(object):
protoc_chart = chartbuilder.get_helm_chart()
# determine install or upgrade by examining known releases
LOG.debug("RELEASE: %s", chart.release_name)
if chart.release_name in [x[0] for x in known_releases]:
# indicate to the end user what path we are taking
LOG.info("Upgrading release %s", chart.release_name)
# extract the installed chart and installed values from the
# latest release so we can compare to the intended state
installed_chart, installed_values = self.find_release_chart(
known_releases, chart.release_name)
if not self.args.disable_update_pre:
pre_actions = getattr(chart.upgrade, 'pre', {})
if not self.args.disable_update_post:
post_actions = getattr(chart.upgrade, 'post', {})
# show delta for both the chart templates and the chart values
# TODO(alanmeadows) account for .files differences
# once we support those
@ -85,7 +94,8 @@ class Armada(object):
# do actual update
self.tiller.update_release(protoc_chart, self.args.dry_run,
chart.release_name,
chart.release_name, chart.namespace,
pre_actions, post_actions,
disable_hooks=chart.
upgrade.no_hooks,
values=yaml.safe_dump(values))
@ -99,6 +109,15 @@ class Armada(object):
chart.namespace,
prefix,
values=yaml.safe_dump(values))
try:
LOG.info("Installing release %s", chart.release_name)
self.tiller.install_release(protoc_chart,
self.args.dry_run,
chart.release_name,
chart.namespace,
values=yaml.safe_dump(values))
except Exception:
LOG.error("Install failed, continuing.")
LOG.debug("Cleaning up chart source in %s",
chartbuilder.source_directory)

View File

@ -135,7 +135,11 @@ class ChartBuilder(object):
for root, _, files in os.walk(os.path.join(self.source_directory,
'templates'), topdown=True):
for tpl_file in files:
templates.append(Template(name=tpl_file,
tname = os.path.relpath(os.path.join(root, tpl_file),
os.path.join(self.source_directory,
'templates'))
templates.append(Template(name=tname,
data=open(os.path.join(root,
tpl_file),
'r').read()))

View File

@ -1,4 +1,6 @@
from kubernetes import client, config
from kubernetes.client.rest import ApiException
from logutil import LOG
class K8s(object):
'''
@ -10,3 +12,33 @@ class K8s(object):
'''
config.load_kube_config()
self.client = client.CoreV1Api()
self.api_client = client.BatchV1Api()
def delete_job_action(self, name, namespace="default"):
'''
:params name - name of the job
:params namespace - name of pod that job
'''
try:
body = client.V1DeleteOptions()
self.api_client.delete_namespaced_job(name=name,
namespace=namespace,
body=body)
except ApiException as e:
LOG.error("Exception when deleting a job: %s", e)
def create_job_action(self, name, namespace="default"):
'''
:params name - name of the job
:params namespace - name of pod that job
'''
LOG.debug(" %s in namespace: %s", name, namespace)
def get_namespace_pod(self, namespace="default"):
'''
:params - namespace - pod namespace
This will return a list of objects req namespace
'''
res = self.client.list_namespaced_pod(namespace)
return res

View File

@ -3,12 +3,13 @@ from hapi.services.tiller_pb2 import ReleaseServiceStub, ListReleasesRequest, \
from hapi.chart.config_pb2 import Config
import grpc
from logutil import LOG
from k8s import K8s
from logutil import LOG
TILLER_PORT = 44134
TILLER_VERSION = b'2.1.3'
TILLER_TIMEOUT = 300
RELEASE_LIMIT = 64
class Tiller(object):
'''
@ -48,8 +49,7 @@ class Tiller(object):
'''
Search all namespaces for a pod beginning with tiller-deploy*
'''
ret = self.k8s.client.list_pod_for_all_namespaces()
for i in ret.items:
for i in self.k8s.get_namespace_pod('kube-system').items:
# TODO(alanmeadows): this is a bit loose
if i.metadata.name.startswith('tiller-deploy'):
return i
@ -69,9 +69,14 @@ class Tiller(object):
'''
List Helm Releases
'''
releases = []
stub = ReleaseServiceStub(self.channel)
req = ListReleasesRequest()
return stub.ListReleases(req, self.timeout, metadata=self.metadata)
req = ListReleasesRequest(limit=RELEASE_LIMIT)
release_list = stub.ListReleases(req, self.timeout,
metadata=self.metadata)
for y in release_list:
releases.extend(y.releases)
return releases
def list_charts(self):
'''
@ -80,9 +85,8 @@ class Tiller(object):
Returns list of (name, version, chart, values)
'''
charts = []
for x in self.list_releases():
for latest_release in self.list_releases():
try:
latest_release = x.releases[-1]
charts.append((latest_release.name, latest_release.version,
latest_release.chart,
latest_release.config.raw))
@ -90,8 +94,49 @@ class Tiller(object):
continue
return charts
def update_release(self, chart, dry_run, name, disable_hooks=False,
values=None):
def _pre_update_actions(self, actions, namespace):
'''
:params actions - array of items actions
:params namespace - name of pod for actions
'''
try:
for action in actions.get('delete', []):
name = action.get("name")
action_type = action.get("type")
if "job" in action_type:
LOG.info("Deleting %s in namespace: %s", name, namespace)
self.k8s.delete_job_action(name, namespace)
continue
LOG.error("Unable to execute name: %s type: %s ", name, type)
except Exception:
LOG.debug("PRE: Could not delete anything, please check yaml")
try:
for action in actions.get('create', []):
name = action.get("name")
action_type = action.get("type")
if "job" in action_type:
LOG.info("Creating %s in namespace: %s", name, namespace)
self.k8s.create_job_action(name, action_type)
continue
except Exception:
LOG.debug("PRE: Could not create anything, please check yaml")
def _post_update_actions(self, actions, namespace):
try:
for action in actions.get('create', []):
name = action.get("name")
action_type = action.get("type")
if "job" in action_type:
LOG.info("Creating %s in namespace: %s", name, namespace)
self.k8s.create_job_action(name, action_type)
continue
except Exception:
LOG.debug("POST: Could not create anything, please check yaml")
def update_release(self, chart, dry_run, name, namespace,
pre_actions=None, post_actions=None,
disable_hooks=False, values=None):
'''
Update a Helm Release
'''
@ -101,6 +146,8 @@ class Tiller(object):
else:
values = Config(raw=values)
self._pre_update_actions(pre_actions, namespace)
# build release install request
stub = ReleaseServiceStub(self.channel)
release_request = UpdateReleaseRequest(
@ -109,8 +156,11 @@ class Tiller(object):
disable_hooks=disable_hooks,
values=values,
name=name)
return stub.UpdateRelease(release_request, self.timeout,
metadata=self.metadata)
stub.UpdateRelease(release_request, self.timeout,
metadata=self.metadata)
self._post_update_actions(post_actions, namespace)
def install_release(self, chart, dry_run, name, namespace, prefix,
values=None):

View File

@ -11,9 +11,9 @@ armada:
charts:
# silent dependency
- chart: &common
name: common
# silent dependency
- chart: &helm-toolkit
name: helm-toolkit
release_name: null
namespace: null
values: {}
@ -23,19 +23,53 @@ armada:
subpath: helm-toolkit
reference: master
dependencies: []
- chart: &keystone
name: keystone
release_name: keystone
- chart: &mariadb
name: mariadb
release_name: mariadb
namespace: openstack
install:
install:
no_hooks: false
upgrade:
no_hooks: false
pre:
delete:
- Job/keystone-db-sync
- Job/keystone-db-init
delete: []
create: []
post:
delete: []
create: []
values:
endpoints: *endpoints
source:
type: git
location: git://github.com/att-comdev/openstack-helm
subpath: mariadb
reference: master
dependencies:
- *helm-toolkit
- chart: &keystone
name: keystone
release_name: keystone
namespace: openstack
install:
no_hooks: false
upgrade:
no_hooks: false
pre:
delete:
- name: keystone-db-sync
type: job
- name: keystone-db-init
type: job
create:
- name: keystone-db-sync
type: job
- name: keystone-db-init
type: job
post:
delete: []
create: []
values:
endpoints: *endpoints
source:
@ -44,4 +78,4 @@ armada:
subpath: keystone
reference: master
dependencies:
- *common
- *helm-toolkit

View File

@ -19,6 +19,11 @@ def parse_args():
ap.add_argument('-d', '--dry-run', action='store_true', default=False,
required=False, help='Enable dry-run flag on all Tiller'
'Calls')
ap.add_argument('--disable-update-pre', action='store_true', default=False,
required=False, help='Disable pre update actions')
ap.add_argument('--disable-update-post', action='store_true',
default=False, required=False,
help='Disable post update actions')
return ap.parse_args()