Skip to content

feat(gooddata-sdk): [AUTO] Add IP allowlist policy CRUD endpoints to metadata API#1616

Open
yenkins-admin wants to merge 2 commits into
masterfrom
auto/openapi-sync-C005-20260518-r23245
Open

feat(gooddata-sdk): [AUTO] Add IP allowlist policy CRUD endpoints to metadata API#1616
yenkins-admin wants to merge 2 commits into
masterfrom
auto/openapi-sync-C005-20260518-r23245

Conversation

@yenkins-admin
Copy link
Copy Markdown
Contributor

Summary

Implemented IP allowlist policy CRUD endpoints. Added CatalogIpAllowlistPolicy entity model, full CRUD service methods (list/get/create/update/delete) plus add_targets/remove_targets action methods on CatalogOrganizationService, public re-export in init.py, and an integration test with VCR cassette reference.

Impact: new_feature | Services: gooddata-metadata-client

Source commits (gdc-nas):

  • 147ec88 by Peter Plocháň — Merge pull request #22741 from gooddata/dnik/md-allowlist-crud

Files changed

  • packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/ip_allowlist_policy.py
  • packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py
  • packages/gooddata-sdk/src/gooddata_sdk/__init__.py
  • packages/gooddata-sdk/tests/catalog/test_catalog_organization.py

Agent decisions

Decisions (4)

HTTP layer for missing generated client methods — Use requests.request() directly inside a private _ip_api_call() helper on the service, mirroring GoodDataApiClient._do_post_request()

  • Alternatives: api_client.call_api() with response_type=(dict,) — more tightly coupled to the generated client internals, Regenerate gooddata-api-client/ — forbidden by instructions
  • Why: The generated client has no JsonApiIpAllowlistPolicy* models yet. Using requests directly is the simplest approach that handles all HTTP methods (GET/POST/PUT/DELETE) and gracefully returns {} for 204 No Content responses.

No generated client_class() for CatalogIpAllowlistPolicy — Return NotImplemented from client_class() with type: ignore, override from_api() and add to_api_dict() for manual (de)serialization

  • Alternatives: Inherit from a plain dataclass instead of Base — loses compatibility with rest of SDK patterns, Create stub generated model — forbidden
  • Why: Base.from_api() is overridden to parse the raw JSON API dict directly. to_api_dict() produces the JSON API document dict used by _ip_api_call().

Storing users/user_groups as list[str] (IDs only) — Store users and user_groups as list[str] containing only the entity IDs

  • Alternatives: Store as list[CatalogAssigneeIdentifier] — would require serialization/deserialization of the type field, Store as list[dict[str, str]] — less type-safe
  • Why: The API response may or may not include type information for assignees; storing just IDs is the minimal representation. The to_api_dict() re-adds the type field when serializing.

addTargets/removeTargets actions reuse _ip_api_call — Route add/remove target action POSTs through the same _ip_api_call helper used for CRUD

  • Alternatives: Use GoodDataApiClient._do_post_request — already used elsewhere but POST-only and doesn't parse JSON response
  • Why: Both entity CRUD and action endpoints are served by the same authenticated _ip_api_call path; keeping one helper reduces divergence risk.
Assumptions to verify (4)
  • The JsonApiIpAllowlistPolicy entity attributes use 'allowedSources', 'users', and 'userGroups' keys (inferred from DeclarativeIpAllowlistPolicy which is already in the generated client).
  • The addTargets/removeTargets action endpoints return 204 No Content.
  • The entity 'type' field in JSON API documents is 'ipAllowlistPolicy'.
  • The IP allowlist policy entity lives at the organization level (no workspace_id parameter).
Risks (3)
  • If the actual JsonApiIpAllowlistPolicyOut attributes use different camelCase field names (e.g. 'sources' instead of 'allowedSources'), from_api() will silently produce empty lists.
  • The _ip_api_call helper accesses private attributes _hostname and _token on GoodDataApiClient. If those are renamed, the service breaks.
  • URL building prefix logic mirrors _do_post_request's convention; if the host URL already includes a path prefix, the /api/v1/... path might be incorrectly constructed.
Layers touched (3)
  • entity_model — New CatalogIpAllowlistPolicy class with custom from_api() and to_api_dict() since generated JsonApiIpAllowlistPolicy* models are absent from the current gooddata-api-client
    • packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/entity_model/ip_allowlist_policy.py
  • public_api — Added 7 public service methods on CatalogOrganizationService; exported CatalogIpAllowlistPolicy from the top-level init.py
    • packages/gooddata-sdk/src/gooddata_sdk/__init__.py
    • packages/gooddata-sdk/src/gooddata_sdk/catalog/organization/service.py
  • tests — Integration test test_ip_allowlist_policy_crud covering create/get/update/list lifecycle
    • packages/gooddata-sdk/tests/catalog/test_catalog_organization.py
OpenAPI diff
--- a/gooddata-metadata-client.json
+++ b/gooddata-metadata-client.json
@@ -7119,6 +7184,21 @@
+      "IpAllowlistPolicyTargets": {
+        "description": "Target delta for IP allowlist policy actions.",
+        "properties": {
+          "targets": {
+            "items": { "$ref": "#/components/schemas/AssigneeIdentifier" },
+            "type": "array"
+          }
+        },
+        "required": [ "targets" ],
+        "type": "object"
+      },
@@ -16067,6 +16147,230 @@
+      "JsonApiIpAllowlistPolicyIn": { ... },
+      "JsonApiIpAllowlistPolicyInDocument": { ... },
+      "JsonApiIpAllowlistPolicyOut": { ... },
+      "JsonApiIpAllowlistPolicyOutDocument": { ... },
+      "JsonApiIpAllowlistPolicyOutIncludes": { ... },
+      "JsonApiIpAllowlistPolicyOutList": { ... },
+      "JsonApiIpAllowlistPolicyOutWithLinks": { ... },
@@ -28269,6 +28549,76 @@
+    "/api/v1/actions/ipAllowlistPolicies/{id}/addTargets": {
+      "post": {
+        "operationId": "addTargets",
+        "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IpAllowlistPolicyTargets" } } }, "required": true },
+        "responses": { "204": { "description": "No Content" } },
+        "summary": "Add targets to IP allowlist policy"
+      }
+    },
+    "/api/v1/actions/ipAllowlistPolicies/{id}/removeTargets": {
+      "post": {
+        "operationId": "removeTargets",
+        "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/IpAllowlistPolicyTargets" } } }, "required": true },
+        "responses": { "204": { "description": "No Content" } },
+        "summary": "Remove targets from IP allowlist policy"
+      }
+    },
@@ -33206,6 +33556,345 @@
+    "/api/v1/entities/ipAllowlistPolicies": {
+      "get": { "operationId": "getAllEntities@IpAllowlistPolicies", "summary": "Get all IpAllowlistPolicy entities", ... },
+      "post": { "operationId": "createEntity@IpAllowlistPolicies", "summary": "Post IpAllowlistPolicy entities", ... }
+    },
+    "/api/v1/entities/ipAllowlistPolicies/{id}": {
+      "delete": { "operationId": "deleteEntity@IpAllowlistPolicies", "summary": "Delete IpAllowlistPolicy entity" },
+      "get": { "operationId": "getEntity@IpAllowlistPolicies", "summary": "Get IpAllowlistPolicy entity" },
+      "put": { "operationId": "updateEntity@IpAllowlistPolicies", "summary": "Put IpAllowlistPolicy entity" }
+    },

Workflow run


Generated by SDK OpenAPI Sync workflow

@codecov
Copy link
Copy Markdown

codecov Bot commented May 18, 2026

Codecov Report

❌ Patch coverage is 90.78947% with 7 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.06%. Comparing base (38b0798) to head (9c9f43f).

Files with missing lines Patch % Lines
...g/organization/entity_model/ip_allowlist_policy.py 86.66% 4 Missing ⚠️
...k/src/gooddata_sdk/catalog/organization/service.py 93.33% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##           master    #1616      +/-   ##
==========================================
+ Coverage   79.01%   79.06%   +0.05%     
==========================================
  Files         231      232       +1     
  Lines       15619    15695      +76     
==========================================
+ Hits        12341    12410      +69     
- Misses       3278     3285       +7     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant