--
Ticket URL: <https://code.djangoproject.com/ticket/27801>
Django <https://code.djangoproject.com/>
The Web framework for perfectionists with deadlines.
* owner: nobody => lsmag
* status: new => assigned
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:1>
Comment (by Tim Graham):
I'm not certain if using `createsuperuser` in non-interactive mode with
environment variables is simpler than writing a
[https://docs.djangoproject.com/en/stable/topics/settings/#calling-django-
setup-is-required-for-standalone-django-usage standalone script] to handle
this use case. Did you give any thought to this?
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:2>
Comment (by Markus Holtermann):
Replying to [comment:2 Tim Graham]:
> I'm not certain if using `createsuperuser` in non-interactive mode with
environment variables is simpler than writing a
[https://docs.djangoproject.com/en/stable/topics/settings/#calling-django-
setup-is-required-for-standalone-django-usage standalone script] to handle
this use case. Did you give any thought to this?
Yes, I gave it some thought. The logic in `createsuperuser` for ensuring
all required fields are present, selecting the right database, etc is
already there. With more and more automated deployments for Django
projects I think having this feature built-in is essential.
I think I'd have `createsuperuser` fallback to the environment variables
if they are present unless fields are overridden by command line
arguments:
{{{#!python
user_data = {}
for field in required_fields:
if field in options:
user_data[field] = options[field]
elif 'DJANGO_SUPERUSER_' + field.upper() in os.environ:
user_data[field] = os.environ['DJANGO_SUPERUSER_' + field.upper()]
elif options['interactive']:
user_data[field] = ask_for_field_value(field)
else:
raise CommandError('Missing value for %s' % field)
}}}
That's a rough draft!
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:3>
Comment (by Tim Graham):
I guess it could help to define the scope of the use case. Would this be
meant for creating one initial superuser. Should it ease creating many
superusers?
That might help clarify the need to have all fields pulled from
environment variables rather than just the password. This seems to add
some complication and I'd like to keep things as simple as possible.
I think the minimal script for anything more complicated is
straightforward. If you're running in non-interactive mode, error handling
doesn't seem like a priority.
{{{
import django
django.setup()
from django.contrib.auth import get_user_model
UserModel = get_user_model()
UserModel._default_manager.db_manager('default').create_superuser()
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:4>
Comment (by Markus Holtermann):
It's for the initial superuser when you can't run the management command
in interactive mode. The only field as for `AbstractBaseUser` is
`password` that needs to be passed via environment variables. However, if
you have another required field that contains sensitive parameters (e.g.
API key) and that is a required field you want to have that handled
through environment variables as well.
Hence my though, let's use the command arguments in the first place (e.g.
for username), fallback to environment variables (that allows for
sensitive values) and fail if that's not defined. I'm not sure if we
_need_ support for env vars in the interactive mode, i believe it wouldn't
hurt, though. Not sure how complex that change might get if that's added.
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:5>
* stage: Unreviewed => Accepted
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:6>
Comment (by Jon Dufresne):
Another potential script friendly solution would be to read the password
from a file. Other non-Django commands implement such a feature. For
example, [https://linux.die.net/man/1/ldapsearch ldapsearch -y passwdfile]
and the [https://www.postgresql.org/docs/current/static/libpq-pgpass.html
PostgreSQL password file].
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:7>
* owner: lsmag => James Pic
* cc: James Pic (added)
* has_patch: 0 => 1
* easy: 0 => 1
Comment:
For our use case, SUPERUSER_PASSWORD works to drop the dependency to
expect in automation code.
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:8>
* needs_docs: 0 => 1
* easy: 1 => 0
* needs_tests: 0 => 1
Comment:
Not sure if that would completely address the ticket, but the patch is
incomplete without tests and documentation.
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:9>
Comment (by James Pic):
FTR there is an external solution for this that you can install with PyPi
package djcli
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:10>
* owner: James Pic => Hasan Ramezani
Comment:
@Tim Graham, do we still need this? do you prefer to read the password
from the file or environment variable?
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:11>
* needs_docs: 1 => 0
* needs_tests: 1 => 0
Comment:
I made a [https://github.com/django/django/pull/11501 PR] to read the
password from environment variables in the non-interactive mode.
Based on the use case proposed on ticket, this feature could be used in
scripting. and the only thing that we can not provide it in non-
interactive mode is `password`.
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:12>
* needs_better_patch: 0 => 1
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:13>
* needs_better_patch: 1 => 0
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:14>
* status: assigned => closed
* resolution: => fixed
Comment:
In [changeset:"a5308514fb4bc5086c9a16a8a24a945eeebb073c" a530851]:
{{{
#!CommitTicketReference repository=""
revision="a5308514fb4bc5086c9a16a8a24a945eeebb073c"
Fixed #27801 -- Made createsuperuser fall back to environment variables
for password and required fields.
}}}
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:15>
Comment (by James Pic):
FTR, I fixed my issue among others in an external package:
https://pypi.org/project/djcli/
--
Ticket URL: <https://code.djangoproject.com/ticket/27801#comment:16>