Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add provision_server management command #4975

Merged
merged 8 commits into from
Jul 10, 2024
Merged

Add provision_server management command #4975

merged 8 commits into from
Jul 10, 2024

Conversation

RuthShryock
Copy link
Member

@RuthShryock RuthShryock commented Jun 10, 2024

Checklist

  1. If you've added code that should be tested, add tests
  2. If you've changed APIs, update (or create!) the documentation
  3. Ensure the tests pass
  4. Make sure that your code lints and that you've followed our coding style
  5. Write a title and, if necessary, a description of your work suitable for publishing in our release notes
  6. Mention any related issues in this repository (as #ISSUE) and in other repositories (as kobotoolbox/other#ISSUE)
  7. Open an issue in the docs if there are UI/UX changes

Description

Automates setup of social applications and constance configurations through running ./manage.py provision_server along with specified arguments.

Notes

This command has two subcommands socialapp and config.
Example: ./manage.py provision_server config MFA_ENABLED=False SUPERUSER_AUTH_ENFORCEMENT=True will disable MFA and enable authentication for superusers.
(The config subcommand can take an infinite number of key-value pairs.)

@RuthShryock RuthShryock changed the title Add management command to insert a social application Add 'provision_server' management command Jun 11, 2024
@RuthShryock RuthShryock changed the title Add 'provision_server' management command Add provision_server management command Jun 11, 2024
@RuthShryock RuthShryock marked this pull request as ready for review June 11, 2024 15:19
@RuthShryock RuthShryock requested a review from bufke June 11, 2024 15:19
…y using key-value pairs and add handling for json and boolean values
Copy link
Contributor

@bufke bufke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would expect this to work but it doesn't /manage.py provision_server socialapp --provider goog --provider_id g --name name --client_id abc --settings "{}" is it easy to allow keyword arguments? It would make it easier to omit optional values.


class Command(BaseCommand):
help = (
'Provision server settings including social apps and constance configs'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the documentation in general, good work. Especially the argument docs. I would add an example command here too, for quick learning.

kpi/management/commands/provision_server.py Outdated Show resolved Hide resolved
}

social_app, created = SocialApp.objects.get_or_create(
defaults=social_app_data
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't work, you need to have a lookup based on a unique field - maybe name? The first time it works. Then with a different name, I still get "Social app for my_first_name already exists" even though I changed the name.

social_app=social_app
).exists()

if not social_app_custom_data_exists:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd probably inline this as it's setting a variable that is used exactly once. Minor, fine-to-ignore, comment.

if value.startswith('[') and value.endswith(']'):
try:
value = json.loads(value)
value = json.dumps(value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting way to validate json, I imagine it works fine. I don't think it's possible to error in the dumps line, so that can be moved outside of the try, except.

Or actually I think you could achieve the validation with

try:
   json.loads(value)
except json.JSONDecodeError ...

you don't really need the value, right? You're just converting to and then from json to validate it I assume.

If you end up keeping this code - I might try to break it out so it's not so nested. I don't typically say one must "Don't repeat yourself" when repeating just twice. But in this case it might help reduce the nesting.

'PROJECT_METADATA_FIELDS',
'USER_METADATA_FIELDS',
]:
if value.startswith('[') and value.endswith(']'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this needed? I know that json technically isn't supposed to start with an array. But this works for me

>>> data = "[1, 2]"
>>> import json
>>> json.loads(data)
[1, 2]
>>> json.dumps(json.loads(data))
'[1, 2]'

…ion logic, and add more example documentation
@RuthShryock RuthShryock requested a review from bufke June 28, 2024 21:49
Copy link

Task 3 - helm automation

f'Invalid JSON value for key {key}. {e}'
)
continue
json.dumps(value)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this does anything, does it? It serializes to a string but the result isn't saved anywhere.

provider_id = kwargs['provider_id']
name = kwargs['name']
client_id = kwargs['client_id']
secret = os.getenv('SOCIAL_APP_SECRET') or kwargs.get('secret', '')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Very minor but if you could do this

kwargs.get('secret', os.getenv('SOCIAL_APP_SECRET', ''))

That would prefer the kwarg over the env var (Seems right to me) 🤷

try:
settings = json.loads(settings_json)
except TypeError:
raise json.JSONDecodeError
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is catching the same error and then re-raising it? Why not allow the original exception to be raised? If you want to catch it and add more context, do that. Or leave it alone. Catching and raising without any benefit is obfuscating the error.

social_app_data = {
'provider': provider,
'provider_id': provider_id,
'name': name,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line can be omitted, you don't need to repeat the args in get_or_create again in defaults. The usage of get_or_create makes a lot of sense though.

@bufke bufke assigned RuthShryock and unassigned bufke Jul 4, 2024
@RuthShryock RuthShryock requested a review from bufke July 9, 2024 18:05
Copy link
Contributor

@bufke bufke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I'm pretty sure I can just merge after this one change.

kpi/management/commands/provision_server.py Show resolved Hide resolved
kpi/management/commands/provision_server.py Show resolved Hide resolved
@bufke bufke merged commit 39b06fc into beta Jul 10, 2024
5 checks passed
@bufke bufke deleted the add-management-command branch July 10, 2024 14:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants