-
Notifications
You must be signed in to change notification settings - Fork 2
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
✨ [#100] Add ConfigurationStep for Service model #99
Merged
Merged
Changes from all commits
Commits
Show all changes
5 commits
Select commit
Hold shift + click to select a range
6b89e06
:heavy_plus_sign: [#100] Add optional django-setup-configuration depe…
stevenbal 130b0d4
:sparkles: [#100] Add ConfigurationStep for Service model
stevenbal bf03b04
:white_check_mark: [#100] Add tests for ServiceConfigurationStep
stevenbal a707cd7
:recycle: [#100] Change several implementation details after discussion
stevenbal 2e4516a
:white_check_mark: [#100] Tests with required service fields and all …
stevenbal File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,6 +17,7 @@ python: | |
- docs | ||
- db | ||
- drf | ||
- setup-configuration | ||
|
||
sphinx: | ||
configuration: docs/conf.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -48,6 +48,7 @@ | |
"simple_certmanager", | ||
"solo", | ||
"testapp", | ||
"django_setup_configuration", | ||
] | ||
|
||
MIDDLEWARE = [ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
zgw_consumers_config_enable: True | ||
zgw_consumers: | ||
services: | ||
- identifier: objecten-test | ||
label: Objecten API test | ||
api_root: http://objecten.local/api/v1/ | ||
api_connection_check_path: objects | ||
api_type: orc | ||
auth_type: api_key | ||
header_key: Authorization | ||
header_value: Token foo | ||
- identifier: zaken-test | ||
label: Zaken API test | ||
api_root: http://zaken.local/api/v1/ | ||
api_type: zrc | ||
auth_type: zgw | ||
client_id: client | ||
secret: super-secret |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
zgw_consumers_config_enable: True | ||
zgw_consumers: | ||
services: | ||
- identifier: objecten-test | ||
label: Objecten API test | ||
api_root: http://objecten.local/api/v1/ | ||
api_connection_check_path: objects | ||
api_type: orc | ||
auth_type: api_key | ||
header_key: Authorization | ||
header_value: Token foo | ||
client_id: client | ||
secret: super-secret | ||
nlx: http://some-outway-adress.local:8080/ | ||
user_id: open-formulieren | ||
user_representation: Open Formulieren | ||
timeout: 5 | ||
# NOT SUPPORTED YET | ||
# client_certificatie: ... | ||
# server_certificatie: ... |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
zgw_consumers_config_enable: True | ||
zgw_consumers: | ||
services: | ||
- identifier: objecten-test | ||
label: Objecten API test | ||
api_root: http://objecten.local/api/v1/ | ||
api_type: orc | ||
auth_type: zgw |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
import pytest | ||
from django_setup_configuration.test_utils import execute_single_step | ||
|
||
from zgw_consumers.constants import APITypes, AuthTypes | ||
from zgw_consumers.contrib.setup_configuration.steps import ServiceConfigurationStep | ||
from zgw_consumers.models import Service | ||
from zgw_consumers.test.factories import ServiceFactory | ||
|
||
CONFIG_FILE_PATH = "tests/files/setup_config_services.yaml" | ||
CONFIG_FILE_PATH_REQUIRED_FIELDS = ( | ||
"tests/files/setup_config_services_required_fields.yaml" | ||
) | ||
CONFIG_FILE_PATH_ALL_FIELDS = "tests/files/setup_config_services_all_fields.yaml" | ||
|
||
|
||
@pytest.mark.django_db | ||
def test_execute_configuration_step_success(): | ||
execute_single_step(ServiceConfigurationStep, yaml_source=CONFIG_FILE_PATH) | ||
|
||
assert Service.objects.count() == 2 | ||
|
||
objects_service, zaken_service = Service.objects.all() | ||
|
||
assert objects_service.slug == "objecten-test" | ||
assert objects_service.label == "Objecten API test" | ||
assert objects_service.api_root == "http://objecten.local/api/v1/" | ||
assert objects_service.api_type == APITypes.orc | ||
assert objects_service.auth_type == AuthTypes.api_key | ||
assert objects_service.header_key == "Authorization" | ||
assert objects_service.header_value == "Token foo" | ||
assert objects_service.timeout == 10 | ||
|
||
assert zaken_service.slug == "zaken-test" | ||
assert zaken_service.label == "Zaken API test" | ||
assert zaken_service.api_root == "http://zaken.local/api/v1/" | ||
assert zaken_service.api_type == APITypes.zrc | ||
assert zaken_service.auth_type == AuthTypes.zgw | ||
assert zaken_service.client_id == "client" | ||
assert zaken_service.secret == "super-secret" | ||
assert zaken_service.timeout == 10 | ||
|
||
|
||
@pytest.mark.django_db | ||
def test_execute_configuration_step_update_existing(): | ||
ServiceFactory.create( | ||
slug="zaken-test", | ||
label="Objecttypen", | ||
api_root="http://some.existing.service.local/api/v1/", | ||
) | ||
|
||
execute_single_step(ServiceConfigurationStep, yaml_source=CONFIG_FILE_PATH) | ||
|
||
assert Service.objects.count() == 2 | ||
|
||
objects_service, zaken_service = Service.objects.all() | ||
|
||
assert objects_service.slug == "objecten-test" | ||
assert objects_service.label == "Objecten API test" | ||
assert objects_service.api_root == "http://objecten.local/api/v1/" | ||
|
||
assert zaken_service.slug == "zaken-test" | ||
assert zaken_service.label == "Zaken API test" | ||
assert zaken_service.api_root == "http://zaken.local/api/v1/" | ||
|
||
|
||
@pytest.mark.django_db | ||
def test_execute_configuration_step_with_required_fields(): | ||
execute_single_step( | ||
ServiceConfigurationStep, yaml_source=CONFIG_FILE_PATH_REQUIRED_FIELDS | ||
) | ||
|
||
assert Service.objects.count() == 1 | ||
|
||
objects_service = Service.objects.get() | ||
|
||
assert objects_service.slug == "objecten-test" | ||
assert objects_service.label == "Objecten API test" | ||
assert objects_service.api_root == "http://objecten.local/api/v1/" | ||
assert objects_service.api_type == APITypes.orc | ||
assert objects_service.auth_type == AuthTypes.zgw | ||
assert objects_service.timeout == 10 | ||
|
||
# Not required fields | ||
assert objects_service.api_connection_check_path == "" | ||
assert objects_service.header_key == "" | ||
assert objects_service.header_value == "" | ||
assert objects_service.client_id == "" | ||
assert objects_service.secret == "" | ||
assert objects_service.nlx == "" | ||
assert objects_service.user_id == "" | ||
assert objects_service.user_representation == "" | ||
|
||
|
||
@pytest.mark.django_db | ||
def test_execute_configuration_step_with_all_fields(): | ||
execute_single_step( | ||
ServiceConfigurationStep, yaml_source=CONFIG_FILE_PATH_ALL_FIELDS | ||
) | ||
|
||
assert Service.objects.count() == 1 | ||
|
||
objects_service = Service.objects.get() | ||
|
||
assert objects_service.slug == "objecten-test" | ||
assert objects_service.label == "Objecten API test" | ||
assert objects_service.api_root == "http://objecten.local/api/v1/" | ||
assert objects_service.api_type == APITypes.orc | ||
assert objects_service.auth_type == AuthTypes.api_key | ||
assert objects_service.api_connection_check_path == "objects" | ||
assert objects_service.header_key == "Authorization" | ||
assert objects_service.header_value == "Token foo" | ||
assert objects_service.client_id == "client" | ||
assert objects_service.secret == "super-secret" | ||
assert objects_service.nlx == "http://some-outway-adress.local:8080/" | ||
assert objects_service.user_id == "open-formulieren" | ||
assert objects_service.user_representation == "Open Formulieren" | ||
assert objects_service.timeout == 5 | ||
|
||
|
||
@pytest.mark.django_db | ||
def test_execute_configuration_step_idempotent(): | ||
def make_assertions(): | ||
assert Service.objects.count() == 1 | ||
|
||
objects_service = Service.objects.get() | ||
|
||
assert objects_service.slug == "objecten-test" | ||
assert objects_service.label == "Objecten API test" | ||
assert objects_service.api_root == "http://objecten.local/api/v1/" | ||
assert objects_service.api_type == APITypes.orc | ||
assert objects_service.auth_type == AuthTypes.api_key | ||
assert objects_service.api_connection_check_path == "objects" | ||
assert objects_service.header_key == "Authorization" | ||
assert objects_service.header_value == "Token foo" | ||
assert objects_service.client_id == "client" | ||
assert objects_service.secret == "super-secret" | ||
assert objects_service.nlx == "http://some-outway-adress.local:8080/" | ||
assert objects_service.user_id == "open-formulieren" | ||
assert objects_service.user_representation == "Open Formulieren" | ||
assert objects_service.timeout == 5 | ||
|
||
execute_single_step( | ||
ServiceConfigurationStep, yaml_source=CONFIG_FILE_PATH_ALL_FIELDS | ||
) | ||
|
||
make_assertions() | ||
|
||
execute_single_step( | ||
ServiceConfigurationStep, yaml_source=CONFIG_FILE_PATH_ALL_FIELDS | ||
) | ||
|
||
make_assertions() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
from django_setup_configuration.models import ConfigurationModel, DjangoModelRef | ||
from pydantic import Field | ||
|
||
from zgw_consumers.models import Service | ||
|
||
|
||
class SingleServiceConfigurationModel(ConfigurationModel): | ||
# TODO these should probably be defined in simple_certmanager and referred to? | ||
# client_certificate: FilePath = DjangoModelRef(Service, "client_certificate") | ||
# server_certificate: FilePath = DjangoModelRef(Service, "server_certificate") | ||
# Identifier is mapped to slug, because slug isn't a very descriptive name for devops | ||
identifier: str = DjangoModelRef(Service, "slug") | ||
|
||
class Meta: | ||
django_model_refs = { | ||
Service: [ | ||
"label", | ||
"api_type", | ||
"api_root", | ||
"api_connection_check_path", | ||
"auth_type", | ||
"client_id", | ||
"secret", | ||
"header_key", | ||
"header_value", | ||
"nlx", | ||
"user_id", | ||
"user_representation", | ||
"timeout", | ||
] | ||
} | ||
|
||
|
||
class ServicesConfigurationModel(ConfigurationModel): | ||
services: list[SingleServiceConfigurationModel] = Field(default_factory=list) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
from django_setup_configuration.configuration import BaseConfigurationStep | ||
|
||
from zgw_consumers.models import Service | ||
|
||
from .models import ServicesConfigurationModel | ||
|
||
|
||
class ServiceConfigurationStep(BaseConfigurationStep[ServicesConfigurationModel]): | ||
""" | ||
Configure Services to connect with external APIs | ||
""" | ||
|
||
verbose_name = "Configuration to connect with external services" | ||
config_model = ServicesConfigurationModel | ||
namespace = "zgw_consumers" | ||
sergei-maertens marked this conversation as resolved.
Show resolved
Hide resolved
|
||
enable_setting = "zgw_consumers_config_enable" | ||
|
||
def execute(self, model: ServicesConfigurationModel): | ||
for config in model.services: | ||
Service.objects.update_or_create( | ||
slug=config.identifier, | ||
defaults={ | ||
stevenbal marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"label": config.label, | ||
"api_type": config.api_type, | ||
swrichards marked this conversation as resolved.
Show resolved
Hide resolved
|
||
"api_root": config.api_root, | ||
"api_connection_check_path": config.api_connection_check_path, | ||
"auth_type": config.auth_type, | ||
"client_id": config.client_id, | ||
"secret": config.secret, | ||
"header_key": config.header_key, | ||
"header_value": config.header_value, | ||
"nlx": config.nlx, | ||
"user_id": config.user_id, | ||
"user_representation": config.user_representation, | ||
"timeout": config.timeout, | ||
}, | ||
swrichards marked this conversation as resolved.
Show resolved
Hide resolved
|
||
) |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm checking with Sjoerd if Dimpact uses these currently, if not this might be something for later
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sjoerd told me that Dimpact doesn't use this currently, so I'm leaving this out of scope for now