From f5a3928d4226f409ed3f7efe67aa2fbf6e6c111f Mon Sep 17 00:00:00 2001 From: omby8888 <160610297+omby8888@users.noreply.github.com> Date: Wed, 11 Dec 2024 16:25:06 +0200 Subject: [PATCH] [Integration][Gitlab] Support both private and oauth token authentications (#1199) # Description What: - Added support for OAuth2.0 token - Added OAuth installation specification for Port ## Type of change Please leave one option from the following and delete the rest: - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] New Integration (non-breaking change which adds a new integration) - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) - [ ] Non-breaking change (fix of existing functionality that will not change current behavior) - [ ] Documentation (added/updated documentation)

All tests should be run against the port production environment(using a testing org).

### Core testing checklist - [ ] Integration able to create all default resources from scratch - [ ] Resync finishes successfully - [ ] Resync able to create entities - [ ] Resync able to update entities - [ ] Resync able to detect and delete entities - [ ] Scheduled resync able to abort existing resync and start a new one - [ ] Tested with at least 2 integrations from scratch - [ ] Tested with Kafka and Polling event listeners - [ ] Tested deletion of entities that don't pass the selector ### Integration testing checklist - [x] Integration able to create all default resources from scratch - [x] Resync able to create entities - [x] Resync able to update entities - [x] Resync able to detect and delete entities - [x] Resync finishes successfully - [ ] If new resource kind is added or updated in the integration, add example raw data, mapping and expected result to the `examples` folder in the integration directory. - [ ] If resource kind is updated, run the integration with the example data and check if the expected result is achieved - [ ] If new resource kind is added or updated, validate that live-events for that resource are working as expected - [ ] Docs PR link [here](#) ### Preflight checklist - [ ] Handled rate limiting - [ ] Handled pagination - [ ] Implemented the code in async - [ ] Support Multi account ## Screenshots Include screenshots from your environment showing how the resources of the integration will look. ## API Documentation Provide links to the API documentation used for this integration. --------- Co-authored-by: Tom Tankilevitch <59158507+Tankilevitch@users.noreply.github.com> --- integrations/gitlab/.port/spec.yaml | 12 ++++++++++ integrations/gitlab/CHANGELOG.md | 9 +++++++ .../gitlab/gitlab_integration/events/setup.py | 7 +++--- .../gitlab/gitlab_integration/utils.py | 24 +++++++++++++++---- integrations/gitlab/pyproject.toml | 2 +- 5 files changed, 44 insertions(+), 10 deletions(-) diff --git a/integrations/gitlab/.port/spec.yaml b/integrations/gitlab/.port/spec.yaml index 890648466d..1099ac2db6 100644 --- a/integrations/gitlab/.port/spec.yaml +++ b/integrations/gitlab/.port/spec.yaml @@ -42,5 +42,17 @@ configurations: \"subgroup_events\", \"confidential_issues_events\"]" sensitive: true +saas: + enabled: true + oauthConfiguration: + requiredSecrets: + - name: tokenMapping + value: '{(.oauthData.accessToken): ["**"]} | @json' + description: '"Token mapping for Gitlab OAuth2 integration"' + valuesOverride: + integrationSpec: + gitlabHost: '"https://gitlab.com"' + appSpec: + minimumScheduledResyncInterval: '2h' deploymentMethodOverride: - type: helm diff --git a/integrations/gitlab/CHANGELOG.md b/integrations/gitlab/CHANGELOG.md index f8549d9bb4..de5c2075e8 100644 --- a/integrations/gitlab/CHANGELOG.md +++ b/integrations/gitlab/CHANGELOG.md @@ -7,6 +7,15 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm +0.2.0 (2024-12-11) +==================== + +### Improvements + +- Added support for OAuth2.0 token +- Added OAuth installation specification for Port + + 0.1.147 (2024-12-10) ==================== diff --git a/integrations/gitlab/gitlab_integration/events/setup.py b/integrations/gitlab/gitlab_integration/events/setup.py index c528dcd97c..e97e3a9996 100644 --- a/integrations/gitlab/gitlab_integration/events/setup.py +++ b/integrations/gitlab/gitlab_integration/events/setup.py @@ -1,7 +1,5 @@ from typing import Type, List -from gitlab import Gitlab - from loguru import logger from gitlab_integration.events.event_handler import EventHandler, SystemEventHandler @@ -26,6 +24,7 @@ GitlabEventListenerConflict, GitlabIllegalEventName, ) +from gitlab_integration.utils import generate_gitlab_client event_handler = EventHandler() system_event_handler = SystemEventHandler() @@ -161,7 +160,7 @@ async def create_webhooks_by_client( groups_hooks_events_override: dict[str, WebhookGroupConfig] | None, group_mapping: list[str], ) -> tuple[GitlabService, list[str]]: - gitlab_client = Gitlab(gitlab_host, token) + gitlab_client = generate_gitlab_client(gitlab_host, token) gitlab_service = GitlabService(gitlab_client, app_host, group_mapping) groups_for_webhooks = await gitlab_service.get_filtered_groups_for_webhooks( @@ -203,7 +202,7 @@ async def setup_application( logger.info("Using system hook") validate_use_system_hook(token_mapping) token, group_mapping = list(token_mapping.items())[0] - gitlab_client = Gitlab(gitlab_host, token) + gitlab_client = generate_gitlab_client(gitlab_host, token) gitlab_service = GitlabService(gitlab_client, app_host, group_mapping) setup_system_listeners([gitlab_service]) diff --git a/integrations/gitlab/gitlab_integration/utils.py b/integrations/gitlab/gitlab_integration/utils.py index c39b1cc46e..0d376beb9d 100644 --- a/integrations/gitlab/gitlab_integration/utils.py +++ b/integrations/gitlab/gitlab_integration/utils.py @@ -1,5 +1,6 @@ from typing import List +import gitlab from gitlab import Gitlab from gitlab_integration.gitlab_service import GitlabService from loguru import logger @@ -10,6 +11,23 @@ RETRY_TRANSIENT_ERRORS = True +def generate_gitlab_client(host: str, token: str) -> Gitlab: + try: + gitlab_client = Gitlab( + host, token, retry_transient_errors=RETRY_TRANSIENT_ERRORS + ) + gitlab_client.auth() + logger.info("Successfully authenticated using the provided private token") + except gitlab.exceptions.GitlabAuthenticationError: + gitlab_client = Gitlab( + host, oauth_token=token, retry_transient_errors=RETRY_TRANSIENT_ERRORS + ) + gitlab_client.auth() + logger.info("Successfully authenticated using the provided OAuth2.0 token") + + return gitlab_client + + def get_all_services() -> List[GitlabService]: logic_settings = ocean.integration_config all_tokens_services = [] @@ -18,11 +36,7 @@ def get_all_services() -> List[GitlabService]: f"Creating gitlab clients for {len(logic_settings['token_mapping'])} tokens" ) for token, group_mapping in logic_settings["token_mapping"].items(): - gitlab_client = Gitlab( - logic_settings["gitlab_host"], - token, - retry_transient_errors=RETRY_TRANSIENT_ERRORS, - ) + gitlab_client = generate_gitlab_client(logic_settings["gitlab_host"], token) gitlab_service = GitlabService( gitlab_client, logic_settings["app_host"], group_mapping ) diff --git a/integrations/gitlab/pyproject.toml b/integrations/gitlab/pyproject.toml index 36f49af75b..fe0d027ba8 100644 --- a/integrations/gitlab/pyproject.toml +++ b/integrations/gitlab/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "gitlab" -version = "0.1.147" +version = "0.2.0" description = "Gitlab integration for Port using Port-Ocean Framework" authors = ["Yair Siman-Tov "]