diff --git a/ckan/cli/cli.py b/ckan/cli/cli.py index ac489a4706f..343a21a2f0c 100644 --- a/ckan/cli/cli.py +++ b/ckan/cli/cli.py @@ -5,6 +5,7 @@ import six import click +import sys import ckan.plugins as p import ckan.cli as ckan_cli @@ -46,6 +47,12 @@ def __init__(self, conf=None): def _init_ckan_config(ctx, param, value): + + # This is necessary to allow the user to create + # a config file when one isn't already present + if len(sys.argv) > 1 and sys.argv[1] == 'generate' and not value: + return + ctx.obj = CkanCommand(value) if six.PY2: ctx.meta["flask_app"] = ctx.obj.app.apps["flask_app"]._wsgi_app diff --git a/ckan/cli/generate.py b/ckan/cli/generate.py index b8b7fe33056..2187dc1507e 100644 --- a/ckan/cli/generate.py +++ b/ckan/cli/generate.py @@ -4,6 +4,9 @@ import os import sys import click +import uuid +import string +import secrets from ckan.cli import error_shout @@ -77,3 +80,32 @@ def extension(output_dir): cookiecutter(template_loc, no_input=True, extra_context=context, output_dir=output_dir) + + +@generate.command(name=u'config', + short_help=u'Create a ckan.ini file.') +@click.argument('output_path', nargs=1) +def make_config(output_path): + """Generate a new CKAN configuration ini file.""" + + # Output to current directory if no path is specified + if '/' not in output_path: + output_path = os.path.join(os.getcwd(), output_path) + + cur_loc = os.path.dirname(os.path.abspath(__file__)) + template_loc = os.path.join(cur_loc, '..', 'config', 'deployment.ini_tmpl') + template_variables = { + 'app_instance_uuid': uuid.uuid4(), + 'app_instance_secret': secrets.token_urlsafe(20)[:25] + } + + with open(template_loc, 'r') as file_in: + template = string.Template(file_in.read()) + + try: + with open(output_path, 'w') as file_out: + file_out.writelines(template.substitute(template_variables)) + + except IOError as e: + error_shout(e) + sys.exit(1) diff --git a/ckan/config/deployment.ini_tmpl b/ckan/config/deployment.ini_tmpl index 0da5e347cee..398ea656f55 100644 --- a/ckan/config/deployment.ini_tmpl +++ b/ckan/config/deployment.ini_tmpl @@ -29,13 +29,13 @@ cache_dir = /tmp/%(ckan.site_id)s/ beaker.session.key = ckan # This is the secret token that the beaker library uses to hash the cookie sent -# to the client. `paster make-config` generates a unique value for this each +# to the client. `ckan generate config` generates a unique value for this each # time it generates a config file. -beaker.session.secret = ${app_instance_secret} +beaker.session.secret = $app_instance_secret -# `paster make-config` generates a unique value for this each time it generates +# `ckan generate config` generates a unique value for this each time it generates # a config file. -app_instance_uuid = ${app_instance_uuid} +app_instance_uuid = $app_instance_uuid # repoze.who config who.config_file = %(here)s/who.ini diff --git a/doc/maintaining/installing/install-from-source.rst b/doc/maintaining/installing/install-from-source.rst index a3c62235034..86608f0eb55 100644 --- a/doc/maintaining/installing/install-from-source.rst +++ b/doc/maintaining/installing/install-from-source.rst @@ -181,7 +181,7 @@ Create the CKAN config file: .. parsed-literal:: - paster make-config ckan |development.ini| + ckan generate config |development.ini| Edit the ``development.ini`` file in a text editor, changing the following options: diff --git a/requirements-py2.txt b/requirements-py2.txt index 7a3af7a2074..3ede51432ab 100644 --- a/requirements-py2.txt +++ b/requirements-py2.txt @@ -41,6 +41,7 @@ pysolr==3.6.0 python-dateutil==2.8.0 python-editor==1.0.4 # via alembic python-magic==0.4.15 +python2-secrets==1.0.5 pytz==2016.7 PyUtilib==5.7.1 pyyaml==5.1