Skip to content

Commit f900b26

Browse files
authored
Feature/ckan exec command (#148)
* Add and remove syadmin * search index and other commands
1 parent c1ee8a4 commit f900b26

File tree

2 files changed

+127
-16
lines changed

2 files changed

+127
-16
lines changed

ckan_cloud_operator/providers/ckan/instance/cli.py

Lines changed: 33 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -163,8 +163,10 @@ def ckan_logs(command):
163163

164164

165165
@instance.command('ckan-exec')
166+
@click.argument('INSTANCE_ID')
166167
@click.option('--command', help='command to pass down to ckan CLI, without path to config file')
167-
def ckan_exec(command):
168+
@click.option('--use-paster', help='Use paster over ckan CLI (supported in ckan v2.9)', default=False)
169+
def ckan_exec(instance_id, command, use_paster):
168170
'''
169171
Executes ckan CLI commands
170172
@@ -175,7 +177,7 @@ def ckan_exec(command):
175177
cco ckan instance ckan-exec --command='jobs list'
176178
cco ckan instance ckan-exec --command='dataset show dataset-id'
177179
'''
178-
pass
180+
manager.run_ckan_commands(instance_id, command)
179181

180182

181183
@instance.command('ssh')
@@ -209,24 +211,31 @@ def sysadmin():
209211

210212

211213
@sysadmin.command('add')
212-
@click.argument('USERNAME')
213-
@click.option('--password', help='Passowrd for user if user does not exist')
214+
@click.argument('INSTANCE_ID')
215+
@click.option('--username', required=True, help='User name for user if user does not exist')
216+
@click.option('--password', help='Password for user if user does not exist')
214217
@click.option('--email', help='Valid Email address for user if user does not exist')
215-
def sysadmin_add(username, password, email):
218+
@click.option('--use-paster', help='Use paster over ckan CLI (supported in ckan v2.9)', default=False)
219+
def sysadmin_add(instance_id, username, password, email, use_paster):
216220
'''
217221
Creates or makes given user system administrator
218222
219223
cco ckan instance sysadmin add USERNAME --pasword pasword --email [email protected]
220224
'''
225+
manager.create_ckan_admin_user(instance_id, username, password, email, use_paster)
226+
221227

222228
@sysadmin.command('rm')
223-
@click.argument('USERNAME')
224-
def sysadmin_rm(username):
229+
@click.argument('INSTANCE_ID')
230+
@click.option('--username', required=True, help='Passowrd for user if user does not exist')
231+
@click.option('--use-paster', help='Use paster over ckan CLI (supported in ckan v2.9)', default=False)
232+
def sysadmin_rm(instance_id, username, use_paster):
225233
'''
226234
Removes System administrator privileges from given user
227235
228236
cco ckan instance sysadmin rm USERNAME
229237
'''
238+
manager.delete_ckan_admin_user(instance_id, username, use_paster)
230239

231240

232241
@click.group()
@@ -238,35 +247,45 @@ def solr():
238247

239248

240249
@solr.command('check')
241-
def solr_check():
250+
@click.argument('INSTANCE_ID')
251+
def solr_check(instance_id):
242252
'''
243253
Check the search index
244254
'''
255+
manager.run_solr_commands(instance_id, 'check')
245256

246257
@solr.command('clear')
247-
def solr_clear():
258+
@click.argument('INSTANCE_ID')
259+
def solr_clear(instance_id):
248260
'''
249261
Clear the search index
250262
'''
263+
manager.run_solr_commands(instance_id, 'clear')
251264

252265
@solr.command('rebuild')
253-
def solr_rebuild():
266+
@click.argument('INSTANCE_ID')
267+
def solr_rebuild(instance_id):
254268
'''
255269
Rebuild search index
256270
'''
271+
manager.run_solr_commands(instance_id, 'rebuild')
257272

258273
@solr.command('rebuild-fast')
259-
def solr_rebuild_fast():
274+
@click.argument('INSTANCE_ID')
275+
def solr_rebuild_fast(instance_id):
260276
'''
261277
Reindex with multiprocessing
262278
'''
279+
manager.run_solr_commands(instance_id, 'check')
263280

264281
@solr.command('show')
265-
@click.option('--dataset', help='Dataset name to show index for')
266-
def solr_show(dataset):
282+
@click.argument('INSTANCE_ID')
283+
@click.option('--dataset-id', help='Dataset name to show index for')
284+
def solr_show(instance_id, dataset_id):
267285
'''
268-
show --dataset=dataset-id-or-name
286+
show --dataset-id=dataset-id-or-name
269287
'''
288+
manager.run_solr_commands(instance_id, 'show', dataset_id=dataset_id)
270289

271290
@click.group()
272291
def deployment():

ckan_cloud_operator/providers/ckan/instance/manager.py

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -336,7 +336,7 @@ def set_storage(instance_id, instance_name, dry_run=False):
336336
kubectl.apply(resource)
337337

338338

339-
def create_ckan_admin_user(instance_id_or_name, name, email=None, password=None, dry_run=False):
339+
def create_ckan_admin_user(instance_id_or_name, name, email=None, password=None, dry_run=False, use_paster=False):
340340
if not email:
341341
default_root_domain = routers_manager.get_default_root_domain()
342342
email = f'{name}@{instance_id_or_name}.{default_root_domain}'
@@ -349,7 +349,21 @@ def create_ckan_admin_user(instance_id_or_name, name, email=None, password=None,
349349
'password': password
350350
}
351351
if not dry_run:
352-
deployment_manager.create_ckan_admin_user(instance_id, instance_type, instance, user)
352+
pod_name = _get_running_pod_name(instance_id)
353+
name, password, email = [user[k] for k in ['name', 'password', 'email']]
354+
logs.info(f'Creating CKAN admin user with {name} ({email}) on pod {pod_name}')
355+
356+
if use_paster:
357+
logs.subprocess_check_call(
358+
f'echo y | kubectl -n {instance_id} exec -i {pod_name} -- ckan-paster --plugin=ckan sysadmin -c /etc/ckan/production.ini add {name} password={password} email={email}',
359+
shell=True
360+
)
361+
else:
362+
logs.subprocess_check_call(
363+
f'echo y | kubectl -n {instance_id} exec -i {pod_name} -- ckan --config /etc/ckan/production.ini sysadmin add {name} password={password} email={email}',
364+
shell=True
365+
)
366+
353367
return {
354368
'instance-id': instance_id,
355369
'instance-type': instance_type,
@@ -358,6 +372,84 @@ def create_ckan_admin_user(instance_id_or_name, name, email=None, password=None,
358372
}
359373

360374

375+
def delete_ckan_admin_user(instance_id_or_name, name, dry_run=False, use_paster=False):
376+
instance_id, instance_type, instance = _get_instance_id_and_type(instance_id_or_name)
377+
378+
if not dry_run:
379+
pod_name = _get_running_pod_name(instance_id)
380+
logs.info(f'Removing CKAN admin user {name} from sys-admins')
381+
382+
if use_paster:
383+
logs.subprocess_check_call(
384+
f'echo y | kubectl -n {instance_id} exec -i {pod_name} -- ckan-paster --plugin=ckan sysadmin -c /etc/ckan/production.ini remove {name}',
385+
shell=True
386+
)
387+
else:
388+
logs.subprocess_check_call(
389+
f'echo y | kubectl -n {instance_id} exec -i {pod_name} -- ckan --config /etc/ckan/production.ini sysadmin remove {name}',
390+
shell=True
391+
)
392+
393+
def run_solr_commands(instance_id_or_name, command, dataset_id='', dry_run=False, use_paster=False):
394+
instance_id, instance_type, instance = _get_instance_id_and_type(instance_id_or_name)
395+
396+
if not dry_run:
397+
pod_name = _get_running_pod_name(instance_id)
398+
logs.info(f'Running Search Index {command}')
399+
if use_paster:
400+
answer = logs.subprocess_check_output(
401+
f'kubectl -n {instance_id} exec -i {pod_name} -- ckan-paster --plugin=ckan -c /etc/ckan/production.ini search-index {command}',
402+
shell=True
403+
)
404+
for line in str(answer).replace('\\r', '\\n').split('\\n'):
405+
if line:
406+
logs.info(str(line))
407+
else:
408+
answer = logs.subprocess_check_output(
409+
f'kubectl -n {instance_id} exec -i {pod_name} -- ckan --config /etc/ckan/production.ini search-index {command} {dataset_id}',
410+
shell=True
411+
)
412+
for line in str(answer).replace('\\r', '\\n').split('\\n'):
413+
if line:
414+
logs.info(str(line))
415+
416+
417+
def run_ckan_commands(instance_id_or_name, command, dry_run=False, use_paster=False):
418+
instance_id, instance_type, instance = _get_instance_id_and_type(instance_id_or_name)
419+
if not dry_run:
420+
pod_name = _get_running_pod_name(instance_id)
421+
logs.info(f'Running Search Index {command}')
422+
if use_paster:
423+
answer = logs.subprocess_check_output(
424+
f'kubectl -n {instance_id} exec -i {pod_name} -- ckan-paster --plugin=ckan -c /etc/ckan/production.ini {command}',
425+
shell=True
426+
)
427+
for line in str(answer).replace('\\r', '\\n').split('\\n'):
428+
if line:
429+
logs.info(str(line))
430+
else:
431+
answer = logs.subprocess_check_output(
432+
f'kubectl -n {instance_id} exec -i {pod_name} -- ckan --config /etc/ckan/production.ini {command}',
433+
shell=True
434+
)
435+
for line in str(answer).replace('\\r', '\\n').split('\\n'):
436+
if line:
437+
logs.info(str(line))
438+
439+
440+
def _get_running_pod_name(instance_id):
441+
pod_name = None
442+
while not pod_name:
443+
try:
444+
pod_name = kubectl.get_deployment_pod_name('ckan', instance_id, use_first_pod=True, required_phase='Running')
445+
break
446+
except Exception as e:
447+
logs.warning('Failed to find running ckan pod', str(e))
448+
time.sleep(20)
449+
return pod_name
450+
451+
452+
361453
def _get_instance_id_and_type(instance_id_or_name=None, instance_id=None, required=True):
362454
if instance_id:
363455
logs.debug(f'Getting instance type using instance_id', instance_id=instance_id)

0 commit comments

Comments
 (0)