Skip to content

Commit 880b8de

Browse files
authored
Merge pull request #1135 from janmatzek/jmat-SVS-1199-public-facing-documentation-for-gooddata-pipelines
2 parents b0af95d + 5df217c commit 880b8de

File tree

9 files changed

+959
-1
lines changed

9 files changed

+959
-1
lines changed

CONTRIBUTING.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ The project documentation is done in hugo. To contribute:
6060

6161
2. Run `make new-docs`
6262

63+
3. Open [http://localhost:1313/latest/](http://localhost:1313/latest/) in your browser to see the preview.
64+
6365
The documentation is deployed using manually triggered GitHub workflows.
6466

6567
One logical change is done in one commit.

docs/content/en/latest/api-reference/_index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: "API Reference"
33
linkTitle: "API Reference"
4-
weight: 60
4+
weight: 99
55
navigationLabel: true
66
---
77

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
---
2+
title: "Pipelines Overview"
3+
linkTitle: "Pipelines Overview"
4+
weight: 14
5+
---
6+
7+
GoodData Pipelines contains tools for automating GoodData lifecycle management. Built on top of [GoodData Python SDK](https://www.gooddata.com/docs/python-sdk/latest/), it enables you to programmatically provision and manage workspaces, users, user groups, and their permissions.
8+
9+
For further information, refer to the PIPELINES section in the left navigation menu.
10+
11+
## Installation
12+
13+
Run the following command to install the ``gooddata-pipelines`` package on your system:
14+
15+
```bash
16+
pip install gooddata-pipelines
17+
```
18+
19+
### Requirements
20+
21+
- Python 3.10 or newer
22+
- GoodData.CN or GoodData Cloud
23+
24+
## Examples
25+
26+
Here is an introductory example of how to manage GoodData resources using GoodData Pipelines:
27+
28+
### Provision Child Workspaces
29+
```python
30+
from gooddata_pipelines import WorkspaceFullLoad, WorkspaceProvisioner
31+
32+
# GoodData.CN host URI (e.g., "http://localhost:3000")
33+
host = "http://localhost:3000"
34+
35+
# GoodData.CN user token
36+
token = "some_user_token"
37+
38+
# Initialize the provisioner
39+
provisioner = WorkspaceProvisioner.create(host=host, token=token)
40+
41+
# Gather the definitions of the workspaces you want to create
42+
raw_data: list[dict] = [
43+
{
44+
"parent_id": "demo_parent_workspace",
45+
"workspace_id": "sales_team_workspace",
46+
"workspace_name": "Sales Team Workspace",
47+
"workspace_data_filter_id": "region_filter",
48+
"workspace_data_filter_values": ["north_america"],
49+
},
50+
]
51+
52+
# Validate the data
53+
validated_data = [WorkspaceFullLoad(**item) for item in raw_data]
54+
55+
# Run the provisioning
56+
provisioner.full_load(validated_data)
57+
58+
```
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
title: "GOODDATA PIPELINES"
3+
linkTitle: "GOODDATA PIPELINES"
4+
weight: 60
5+
navigationLabel: true
6+
---
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
---
2+
title: "Provisioning"
3+
linkTitle: "Provisioning"
4+
weight: 1
5+
no_list: true
6+
---
7+
8+
Programmatically manage and provision resources in your GoodData environment.
9+
10+
## Supported Resources
11+
12+
Resources you can provision using GoodData Pipelines:
13+
14+
- [Workspaces](workspaces/)
15+
- [Users](users/)
16+
- [User Groups](user_groups/)
17+
- [Workspace Permissions](workspace-permissions/)
18+
19+
20+
## Workflow Types
21+
22+
There are two types of provisioning supported by GoodData Pipelines:
23+
24+
- [Full load](#full-load)
25+
- [Incremental load](#incremental-load)
26+
27+
The provisioning types employ different algorithms and expect different structures of input data. For details about the expected inputs, check out the documentation page for each individual resource.
28+
29+
### Full Load
30+
31+
Full load provisioning aims to fully synchronize the state of your GoodData instance with the provided input. This workflow will create new resources and update existing ones based on the input. Any resources existing on GoodData Cloud not included in the input will be deleted.
32+
33+
{{% alert color="warning" title="Full loads are destrucitve"%}}
34+
Full load provisioning will delete any existing resources not included in your input data. Test in non-production environment.
35+
{{% /alert %}}
36+
37+
### Incremental Load
38+
39+
During incremental provisioning, the algorithm will only interact with resources specified in the input. During the incremental load, the input data expects an extra parameter: `is_active`. Resources with `True` value will be updated. On the other hand, by setting it to `False`, you can mark resources for deletion. Any other resources already existing in GoodData will not be altered.
40+
41+
### Workflow Comparison
42+
43+
| **Aspect** | **Full Load** | **Incremental Load** |
44+
|------------|---------------|----------------------|
45+
| **Scope** | Synchronizes entire state | Only specified resources |
46+
| **Deletion** | Deletes unspecified resources | Only deletes resources marked `is_active: False` |
47+
| **Use Case** | Complete environment setup | Targeted updates |
48+
49+
## Usage
50+
51+
Regardless of workflow type or resource being provisioned, the typical usage follows these steps:
52+
53+
1. Initialize the provisioner
54+
55+
1. Validate your data using an input model
56+
57+
1. Run the selected provisioning method (`.full_load()` or `.incremental_load()`) with your validated data
58+
59+
60+
Check the [resource pages](#supported-resources) for detailed instructions and examples of workflow implementations.
61+
62+
## Logs
63+
64+
By default, the provisioners operate silently. To monitor progress and troubleshoot issues, you can subscribe to the emitted logs using the `.subscribe()` method on the `logger` property of the provisioner instance.
65+
66+
```python
67+
# Import and set up your logger
68+
import logging
69+
70+
# Import the provisioner
71+
from gooddata_pipelines import WorkspaceProvisioner
72+
73+
host = "http://localhost:3000"
74+
token = "some_user_token"
75+
76+
# In this example, we will use Python standard logging library.
77+
# However, you can use any logger conforming to the LoggerLike protocol
78+
# defined in gooddata_pipelines.logger.logger
79+
logging.basicConfig(level=logging.INFO)
80+
logger = logging.getLogger(__name__)
81+
82+
83+
# Initialize the provisioner
84+
provisioner = WorkspaceProvisioner.create(host=host, token=token)
85+
86+
# Subscribe to the logging service
87+
provisioner.logger.subscribe(logger)
88+
89+
# Continue with the provisioning
90+
...
91+
```
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
title: "User Groups"
3+
linkTitle: "User Group"
4+
weight: 3
5+
---
6+
7+
User group provisioning allows you to create, update, or delete user groups.
8+
9+
User groups enable you to organize users and manage permissions at scale by assigning permissions to groups rather than individual users.
10+
11+
You can provision user groups using full or incremental load methods. Each of these methods requires a specific input type.
12+
13+
## Usage
14+
15+
Start by importing and initializing the UserGroupProvisioner.
16+
17+
```python
18+
19+
from gooddata_pipelines import UserGroupProvisioner
20+
21+
host = "http://localhost:3000"
22+
token = "some_user_token"
23+
24+
# Initialize the provisioner with GoodData credentials
25+
provisioner = UserGroupProvisioner.create(host=host, token=token)
26+
27+
```
28+
29+
30+
Then validate your data using an input model corresponding to the provisioned resource and selected workflow type, i.e., `UserGroupFullLoad` if you intend to run the provisioning in full load mode, or `UserGroupIncrementalLoad` if you want to provision incrementally.
31+
32+
The models expect the following fields:
33+
- **user_group_id**: ID of the user group.
34+
- **user_group_name**: Name of the user group.
35+
- **parent_user_groups**: A list of parent user group IDs.
36+
- _**is_active**:_ Deletion flag. Present only in the IncrementalLoad models.
37+
38+
{{% alert color="info" title="Note on IDs"%}}
39+
Each ID can only contain allowed characters. See [Workspace Object Identification](https://www.gooddata.com/docs/cloud/create-workspaces/objects-identification/) to learn more about object identifiers.
40+
{{% /alert %}}
41+
42+
Use the appropriate model to validate your data:
43+
44+
```python
45+
# Add the model to the imports
46+
from gooddata_pipelines import UserGroupFullLoad, UserGroupProvisioner
47+
48+
host = "http://localhost:3000"
49+
token = "some_user_token"
50+
51+
# Initialize the provisioner with GoodData credentials
52+
provisioner = UserGroupProvisioner.create(host=host, token=token)
53+
54+
# Load your data
55+
raw_data = [
56+
{
57+
"user_group_id": "user_group_1",
58+
"user_group_name": "User Group 1",
59+
"parent_user_groups": [],
60+
},
61+
]
62+
63+
# Validate the data
64+
validated_data = [
65+
UserGroupFullLoad(
66+
user_group_id=item["user_group_id"],
67+
user_group_name=item["user_group_name"],
68+
parent_user_groups=item["parent_user_groups"],
69+
)
70+
for item in raw_data
71+
]
72+
73+
```
74+
75+
Now with the provisioner initialized and your data validated, you can run the provisioner:
76+
77+
```python
78+
# Import, initialize, validate...
79+
...
80+
81+
# Run the provisioning method
82+
provisioner.full_load(validated_data)
83+
84+
```
85+
86+
## Examples
87+
88+
Here are full examples of a full load and incremental load user group provisioning workflows:
89+
90+
### Full Load
91+
92+
```python
93+
import logging
94+
95+
from gooddata_pipelines import UserGroupFullLoad, UserGroupProvisioner
96+
97+
host = "http://localhost:3000"
98+
token = "some_user_token"
99+
100+
# Initialize the provisioner
101+
provisioner = UserGroupProvisioner.create(host=host, token=token)
102+
103+
# Optional: set up logging and subscribe to logs emitted by the provisioner
104+
logging.basicConfig(level=logging.INFO)
105+
logger = logging.getLogger(__name__)
106+
107+
provisioner.logger.subscribe(logger)
108+
109+
# Prepare your data
110+
raw_data = [
111+
{
112+
"user_group_id": "user_group_1",
113+
"user_group_name": "User Group 1",
114+
"parent_user_groups": [],
115+
},
116+
]
117+
118+
# Validate the data
119+
validated_data = [
120+
UserGroupFullLoad(
121+
user_group_id=item["user_group_id"],
122+
user_group_name=item["user_group_name"],
123+
parent_user_groups=item["parent_user_groups"],
124+
)
125+
for item in raw_data
126+
]
127+
128+
# Run the provisioning with the validated data
129+
provisioner.full_load(validated_data)
130+
131+
```
132+
133+
134+
### Incremental Load
135+
136+
```python
137+
import logging
138+
139+
from gooddata_pipelines import UserGroupIncrementalLoad, UserGroupProvisioner
140+
141+
host = "http://localhost:3000"
142+
token = "some_user_token"
143+
144+
# Initialize the provisioner
145+
provisioner = UserGroupProvisioner.create(host=host, token=token)
146+
147+
# Optional: set up logging and subscribe to logs emitted by the provisioner
148+
logging.basicConfig(level=logging.INFO)
149+
logger = logging.getLogger(__name__)
150+
151+
provisioner.logger.subscribe(logger)
152+
153+
# Prepare your data
154+
raw_data = [
155+
{
156+
"user_group_id": "user_group_1",
157+
"user_group_name": "User Group 1",
158+
"parent_user_groups": [],
159+
"is_active": True,
160+
},
161+
]
162+
163+
# Validate the data
164+
validated_data = [
165+
UserGroupIncrementalLoad(
166+
user_group_id=item["user_group_id"],
167+
user_group_name=item["user_group_name"],
168+
parent_user_groups=item["parent_user_groups"],
169+
is_active=item["is_active"],
170+
)
171+
for item in raw_data
172+
]
173+
174+
# Run the provisioning with the validated data
175+
provisioner.incremental_load(validated_data)
176+
177+
```

0 commit comments

Comments
 (0)