Skip to content
This repository was archived by the owner on Jul 1, 2022. It is now read-only.

Commit bafd8d2

Browse files
committed
add improved undeploy command
1 parent 9773714 commit bafd8d2

File tree

1 file changed

+132
-0
lines changed

1 file changed

+132
-0
lines changed

undeploy.py

+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
# vim:set sw=4 ts=4 et:
2+
#
3+
# Copyright (c) 2016-2017 Torchbox Ltd.
4+
#
5+
# Permission is granted to anyone to use this software for any purpose,
6+
# including commercial applications, and to alter it and redistribute it
7+
# freely. This software is provided 'as-is', without any express or implied
8+
# warranty.
9+
10+
import json
11+
from sys import stdout, stderr, exit
12+
from kubernetes.client.apis import core_v1_api, extensions_v1beta1_api
13+
14+
import deployment, kubectl, kubeutil
15+
16+
def undeploy(args):
17+
try:
18+
dp = deployment.get_deployment(args.namespace, args.name)
19+
except Exception as e:
20+
stderr.write('cannot load deployment {0}: {1}\n'.format(
21+
args.name, kubeutil.get_error(e)))
22+
exit(1)
23+
24+
resources = None
25+
try:
26+
resources = json.loads(dp['metadata']['annotations']['kdtool.torchbox.com/attached-resources'])
27+
except KeyError:
28+
pass
29+
except ValueError as e:
30+
stderr.write("error: could not decode kdtool.torchbox.com/attached-resources annotation: {0}\n".format(str(e)))
31+
exit(1)
32+
33+
stdout.write("\nthis deployment will be removed:\n")
34+
stdout.write("- {0}/{1}\n".format(
35+
dp['metadata']['namespace'],
36+
dp['metadata']['name'],
37+
))
38+
39+
if len(resources):
40+
if args.all:
41+
stdout.write("\nthe following attached resources will also be deleted:\n")
42+
for res in resources:
43+
extra = ''
44+
if res['kind'] == 'database':
45+
extra = ' (database will be dropped)'
46+
elif res['kind'] == 'volume':
47+
extra = ' (contents will be deleted)'
48+
49+
stdout.write("- {0}: {1}{2}\n".format(
50+
res['kind'],
51+
res['name'],
52+
extra
53+
))
54+
else:
55+
stdout.write("\nthe following attached resources will NOT be deleted (use --all):\n")
56+
for res in resources:
57+
stdout.write("- {0}: {1}\n".format(
58+
res['kind'],
59+
res['name'],
60+
))
61+
62+
stdout.write('\n')
63+
64+
if not args.force:
65+
pr = input('continue [y/N]? ')
66+
if pr.lower() not in ['yes', 'y']:
67+
stdout.write("okay, aborting\n")
68+
exit(0)
69+
70+
client = kubeutil.get_client()
71+
extv1beta1 = extensions_v1beta1_api.ExtensionsV1beta1Api(client)
72+
v1 = core_v1_api.CoreV1Api(client)
73+
74+
stdout.write('deleting deployment <{}/{}>: '.format(args.namespace, args.name))
75+
extv1beta1.delete_namespaced_deployment(args.name, args.namespace, body={})
76+
stdout.write('ok\n')
77+
78+
if not args.all:
79+
exit(0)
80+
81+
for res in resources:
82+
stdout.write('deleting {} <{}>: '.format(res['kind'], res['name']))
83+
if res['kind'] == 'volume':
84+
v1.delete_namespaced_persistent_volume_claim(
85+
res['name'], args.namespace, body={})
86+
elif res['kind'] == 'secret':
87+
v1.delete_namespaced_secret(res['name'], args.namespace, body={})
88+
elif res['kind'] == 'database':
89+
resource_path = ('/apis/torchbox.com/v1/namespaces/'
90+
+ dp['metadata']['namespace']
91+
+ '/databases/'
92+
+ res['name'])
93+
94+
header_params = {}
95+
header_params['Accept'] = client.select_header_accept(['application/json'])
96+
header_params['Content-Type'] = client.select_header_content_type(['*/*'])
97+
header_params.update(kubeutil.config.api_key)
98+
99+
(resp, code, header) = client.call_api(
100+
resource_path, 'DELETE', {}, {}, header_params, None, [], _preload_content=False)
101+
elif res['kind'] == 'service':
102+
v1.delete_namespaced_service(res['name'], args.namespace)
103+
elif res['kind'] == 'ingress':
104+
extv1beta1.delete_namespaced_ingress(res['name'], args.namespace, body={})
105+
106+
stdout.write('ok\n')
107+
108+
undeploy.help = "undeploy an application"
109+
undeploy.arguments = (
110+
( ('-M', '--manifest'), {
111+
'type': str,
112+
'metavar': 'FILE',
113+
'help': 'deploy from Kubernetes manifest with environment substitution',
114+
}),
115+
( ('-f', '--force'), {
116+
'action': 'store_true',
117+
'help': 'do not prompt for confirmation',
118+
}),
119+
( ('-A', '--all'), {
120+
'action': 'store_true',
121+
'help': 'undeploy attached resources',
122+
}),
123+
( ('name',), {
124+
'type': str,
125+
'help': 'application name',
126+
})
127+
)
128+
129+
commands = {
130+
'undeploy': undeploy,
131+
}
132+

0 commit comments

Comments
 (0)