Skip to content

Commit db852cb

Browse files
Merge branch 'main' into fix/STACKITSDK-412-token-leeway
2 parents 895c5a9 + c704ae3 commit db852cb

285 files changed

Lines changed: 20352 additions & 5160 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/stale.yaml‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ on:
99
paths: [".github/workflows/stale.yaml"]
1010

1111
env:
12-
DAYS_BEFORE_PR_STALE: 7
13-
DAYS_BEFORE_PR_CLOSE: 7
12+
DAYS_BEFORE_PR_STALE: 14
13+
DAYS_BEFORE_PR_CLOSE: 14
1414
EXEMPT_PR_LABELS: "ignore-stale"
1515

1616
permissions:

‎CHANGELOG.md‎

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,46 @@
11
## Release (2026-MM-DD)
22

3+
- `alb`:
4+
- [v0.13.0](services/alb/CHANGELOG.md#v0130)
5+
- **Feature:** Add `ip_block_list_name` field to `LoadbalancerOptionAccessControl` model
6+
- `automation`:
7+
- [v0.1.0](services/automation/CHANGELOG.md#v010)
8+
- Initial onboarding of STACKIT Python SDK for Automation service
9+
- `objectstorage`:
10+
- [v1.6.0](services/objectstorage/CHANGELOG.md#v160)
11+
- **Feature:** New model class `RateLimitError`
12+
- **Improvement:** Add HTTP 429 rate limit error responses in API operations
13+
- **Breaking Change:** Field `expires` in `AccessKey` model is now optional (`Optional[StrictStr]`)
14+
- **Improvement:** Field `expires` in `CreateAccessKeyPayload` model now supports explicit `None` serialization
15+
- `resourcemanager`
16+
- [v0.11.1](services/resourcemanager/CHANGELOG.md#0111)
17+
- Update descriptions of `labels` attributes in model classes
18+
- `telemetryrouter`:
19+
- [v0.6.0](services/telemetryrouter/CHANGELOG.md#v060)
20+
- **Feature:** Add `disabled` field to `ConfigFilter` to allow disabling a filter without removing it
21+
- `vpn`:
22+
- [v0.7.3](services/vpn/CHANGELOG.md#v073)
23+
- **Improvement:** Relax maximum `rekey_time` validation to `86400` (previously `28800`) in `TunnelConfigurationPhase1`
24+
- **Improvement:** Relax maximum `rekey_time` validation to `14400` (previously `3600`) in `TunnelConfigurationPhase2`
25+
- [v0.7.2](services/vpn/CHANGELOG.md#v072)
26+
- **Breaking Change:** `predefined_network_prefix` attribute in `NetworkConfig` model class changed type from `Optional[List[str]]` to `Optional[str]` to match actual API behavior
27+
- **Improvement:** Relax minimum ASN validation to `1` (previously `64512`) for `as_path_contains_any` and `first_asn` in `BGPFilterRuleMatch` and `remote_asn` in `BGPTunnelConfig`
28+
29+
## Release (2026-09-14)
30+
331
- `albwaf`:
32+
- [v0.1.2](services/albwaf/CHANGELOG.md#v012)
33+
- **Docs:** Update module description and description of `update_waf` operation
434
- [v0.1.1](services/albwaf/CHANGELOG.md#v011)
535
- **Fix:** Corrected an invalid `pyproject.toml` build configuration (`wheel-sources` instead of `wheel.sources`) that caused `import stackit.albwaf` to fail with `ModuleNotFoundError`
636
- `cost`:
737
- [v0.4.1](services/cost/CHANGELOG.md#v041)
838
- **Fix:** Corrected an invalid `pyproject.toml` build configuration (`wheel-sources` instead of `wheel.sources`) that caused `import stackit.cost` to fail with `ModuleNotFoundError`
39+
- `dns`:
40+
- [v0.9.0](services/dns/CHANGELOG.md#v090)
41+
- **Feature:** `create_move_code` operation now accepts an optional `CreateMoveCodePayload` request body (field `ttl`) to configure the move code's validity duration
42+
- **Breaking Change:** `DomainObservabilityExtension.state` now validates against a fixed set of values (`CREATING`, `CREATE_SUCCEEDED`, `ERROR`); previously any string was accepted
43+
- **Breaking Change:** Removed `state` field from `ZoneObservabilityExtension`
944
- `dremio`:
1045
- [v0.1.0](services/dremio/CHANGELOG.md#v010)
1146
- **New**: STACKIT Dremio module can be used to manage STACKIT Dremio instances and users.
@@ -29,12 +64,33 @@
2964
- **Breaking Change/Fix:** `create_backup` operation now returns `CreateBackupResponseItem` instead of `List[CreateBackupResponseItem]`
3065
The return type now correctly models the actual JSON response, this operation was broken beforehand.
3166
- `postgresflex`:
67+
- [v1.6.1](services/postgresflex/CHANGELOG.md#v161)
68+
- **Improvement:** Add validation for `name` field in `CreateDatabasePayload`, `DatabaseRoles`, `GetDatabaseResponse`, `ListDatabase`, `PartialUpdateDatabasePayload` and `UpdateDatabasePayload` models
69+
- **Docs:** Extend description of `InstanceNetworkAccessScope` enum to note that the `SNA` value is only permitted for enabled accounts
3270
- [v1.6.0](services/postgresflex/CHANGELOG.md#v160)
3371
- **Breaking Change:** `class` attribute in `CloneInstanceOverrides` and `StorageCreate` model is now required (previously optional)
3472
- `rabbitmq`:
3573
- [v1.3.0](services/rabbitmq/CHANGELOG.md#v130)
3674
- **Breaking Change/Fix:** `create_backup` operation now returns `CreateBackupResponseItem` instead of `List[CreateBackupResponseItem]`
3775
The return type now correctly models the actual JSON response, this operation was broken beforehand.
76+
- `redis`:
77+
- [v1.3.0](services/redis/CHANGELOG.md#v130)
78+
- **Breaking Change/Fix:** `create_backup` operation now returns `CreateBackupResponseItem` instead of `List[CreateBackupResponseItem]`
79+
The return type now correctly models the actual JSON response, this operation was broken beforehand.
80+
- **Deprecation:** Redis service has been deprecated and will be removed after 2027-08-25. Please use the Key Value Store (valkey) service instead.
81+
- `resourcemanager`
82+
- [v0.11.0](services/resourcemanager/CHANGELOG.md#0110)
83+
- Updated pydoc comments of the API client methods
84+
- **Breaking change:** Removal of unused model class `ContainerSearchResult`
85+
- [v0.10.0](services/resourcemanager/CHANGELOG.md#0100)
86+
- **Breaking change:** Labels are nullable now, therefore the `labels` attribute in the `PartialUpdateFolderPayload`, `PartialUpdateOrganizationPayload` and `PartialUpdateProjectPayload` model class changed from `Optional[Dict[str, StrictStr]]` to `Optional[Dict[str, Optional[StrictStr]]]`
87+
- `secretsmanager`:
88+
- [v0.7.0](services/secretsmanager/CHANGELOG.md#v070)
89+
- **Feature:** Add support for managing AppRoles and their secret IDs: new `Approle`, `ApproleList`, `ApproleSecret`, `ApproleSecretList`, `CreateApprolePayload`, `CreateApproleSecretIdPayload`, `UpdateApprolePayload` and `UpdateApproleSecretIdPayload` models, plus new `create_approle`, `get_approle`, `get_approles`, `update_approle`, `delete_approle`, `create_approle_secret_id`, `get_approle_secret_id`, `list_approle_secret_ids`, `update_approle_secret_id` and `delete_approle_secret_id` operations
90+
- `serviceaccount`
91+
- [v0.11.0](services/serviceaccount/CHANGELOG.md#v0110)
92+
- **Breaking change:** Removal of API client methods: `create_access_token`, `delete_access_token`, `list_access_tokens`
93+
- **Breaking change:** Removal of model classes: `AccessToken`, `CreateAccessTokenPayload`, `ListAccessTokensResponse`
3894
- `telemetrylink`:
3995
- [v0.4.2](services/telemetrylink/CHANGELOG.md#v042)
4096
- **Fix:** Corrected an invalid `pyproject.toml` build configuration (`wheel-sources` instead of `wheel.sources`) that caused `import stackit.telemetrylink` to fail with `ModuleNotFoundError`
@@ -45,6 +101,9 @@
45101
- **Fix:** Corrected an invalid `pyproject.toml` build configuration (`wheel-sources` instead of `wheel.sources`) that caused `import stackit.telemetryrouter` to fail with `ModuleNotFoundError`
46102
- [v0.5.1](services/telemetryrouter/CHANGELOG.md#v051)
47103
- **Improvement:** Add validation for `description` field in `AccessTokenBaseRequest`, `AccessTokenBaseResponse`, `CreateAccessTokenPayload`, `CreateAccessTokenResponse`, `DestinationResponse`, `GetAccessTokenResponse`, `TelemetryRouterResponse`, `UpdateAccessTokenPayload` and `UpdateAccessTokenResponse` models
104+
- `ufw`:
105+
- [v0.1.0](services/ufw/CHANGELOG.md#v010)
106+
- **New**: STACKIT Unified Firewall (UFW)
48107
- `valkey`:
49108
- [v0.2.1](services/valkey/CHANGELOG.md#v021)
50109
- **Fix:** Corrected an invalid `pyproject.toml` build configuration (`wheel-sources` instead of `wheel.sources`) that caused `import stackit.valkey` to fail with `ModuleNotFoundError`

‎examples/automation/automation.py‎

Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
1+
import os
2+
import sys
3+
import time
4+
from uuid import UUID
5+
6+
from stackit.automation.api.default_api import DefaultApi
7+
from stackit.automation.models.automation_schedule_trigger import (
8+
AutomationScheduleTrigger,
9+
)
10+
from stackit.automation.models.automation_triggers import AutomationTriggers
11+
from stackit.automation.models.create_volume_automation_payload import (
12+
CreateVolumeAutomationPayload,
13+
)
14+
from stackit.automation.models.partial_update_volume_automation_payload import (
15+
PartialUpdateVolumeAutomationPayload,
16+
)
17+
from stackit.automation.models.volume_automation_input import VolumeAutomationInput
18+
from stackit.core.configuration import Configuration
19+
20+
21+
def main():
22+
# Credentials are read from the credentialsFile in
23+
# `~/.stackit/credentials.json` or the env
24+
# STACKIT_SERVICE_ACCOUNT_KEY_PATH / STACKIT_SERVICE_ACCOUNT_KEY
25+
config = Configuration()
26+
automation_api = DefaultApi(config)
27+
28+
# the id of your STACKIT project, read from env var for this example
29+
project_id = os.getenv("PROJECT_ID")
30+
if not project_id:
31+
print("Environment variable 'PROJECT_ID' not found.", file=sys.stderr)
32+
return
33+
34+
# the region which should be used to interact with the automation service
35+
region = "eu01"
36+
37+
try:
38+
# ///////////////////////////////////////////////////////
39+
# // V O L U M E T E M P L A T E S //
40+
# ///////////////////////////////////////////////////////
41+
42+
# list all available volume templates
43+
list_templates = automation_api.list_volume_templates(project_id=project_id, region=region)
44+
print("Listing volume templates:")
45+
if list_templates.items:
46+
for template in list_templates.items:
47+
print(f"* Template ID: {template.id}")
48+
49+
# if there is a next_page_token, fetch next page of results
50+
while list_templates.next_page_token:
51+
list_templates = automation_api.list_volume_templates(
52+
project_id=project_id,
53+
region=region,
54+
page_token=list_templates.next_page_token,
55+
)
56+
print("Listing next page of volume templates:")
57+
if list_templates.items:
58+
for template in list_templates.items:
59+
print(f"* Template ID: {template.id}")
60+
61+
if not list_templates.items:
62+
print("No volume templates found.")
63+
return
64+
65+
# get one specific volume template
66+
template = automation_api.get_volume_template(
67+
project_id=project_id,
68+
region=region,
69+
template_id=str(list_templates.items[0].id),
70+
)
71+
print("\n\nFetched volume template:")
72+
print(f"* Template ID: {template.id}")
73+
print(f"* Template name: {template.name}")
74+
print(f"* Template description: {template.description}")
75+
76+
# ///////////////////////////////////////////////////////
77+
# // V O L U M E A U T O M A T I O N //
78+
# ///////////////////////////////////////////////////////
79+
80+
# create a volume automation with a schedule trigger
81+
volume_automation = automation_api.create_volume_automation(
82+
project_id=project_id,
83+
region=region,
84+
create_volume_automation_payload=CreateVolumeAutomationPayload(
85+
description="Creates daily recovery points for all volumes with specified label",
86+
name="My Daily Volume Recovery Point Creation Automation",
87+
template_id=UUID(str(template.id)),
88+
input=VolumeAutomationInput(
89+
kind="VolumeRecoveryPointManagement",
90+
additional_properties={
91+
"inheritVolumeLabels": True,
92+
"recoveryPointLabels": {
93+
"exampleLabelKey1": "exampleLabelValue1",
94+
},
95+
"snapshotRetentionPolicy": {
96+
"kind": "count",
97+
"value": 2,
98+
},
99+
"volumeLabelSelector": "myLabelkey1=myLabelValue,myLabelKey2=myOtherLabelValue",
100+
},
101+
),
102+
triggers=AutomationTriggers(
103+
schedule=AutomationScheduleTrigger(
104+
rrule="DTSTART;TZID=Europe/Sofia:20200803T023000\nRRULE:FREQ=DAILY;INTERVAL=1",
105+
),
106+
),
107+
),
108+
)
109+
print("\n\nCreated volume automation:")
110+
print(f"* Automation ID: {volume_automation.id}")
111+
print(f"* Automation name: {volume_automation.name}")
112+
print(f"* Automation description: {volume_automation.description}")
113+
114+
# list all volume automations
115+
list_automations = automation_api.list_volume_automations(project_id=project_id, region=region)
116+
print("\n\nListing volume automations:")
117+
if list_automations.items:
118+
for automation in list_automations.items:
119+
print(f"* Automation ID: {automation.id}")
120+
121+
# if there is a next_page_token, fetch next page of results
122+
while list_automations.next_page_token:
123+
list_automations = automation_api.list_volume_automations(
124+
project_id=project_id,
125+
region=region,
126+
page_token=list_automations.next_page_token,
127+
)
128+
print("\nListing next page of volume automations:")
129+
if list_automations.items:
130+
for automation in list_automations.items:
131+
print(f"* Automation ID: {automation.id}")
132+
133+
# update an automation
134+
updated_automation = automation_api.partial_update_volume_automation(
135+
project_id=project_id,
136+
region=region,
137+
automation_id=str(volume_automation.id),
138+
partial_update_volume_automation_payload=PartialUpdateVolumeAutomationPayload(
139+
description="Updated daily recovery points automation",
140+
name="Updated Daily Volume Recovery Point Creation Automation",
141+
),
142+
)
143+
print("\n\nUpdated volume automation:")
144+
print(f"* Automation ID: {updated_automation.id}")
145+
print(f"* Automation name: {updated_automation.name}")
146+
print(f"* Automation description: {updated_automation.description}")
147+
148+
# get one specific volume automation
149+
fetched_automation = automation_api.get_volume_automation(
150+
project_id=project_id,
151+
region=region,
152+
automation_id=str(volume_automation.id),
153+
)
154+
print("\n\nFetched updated volume template:")
155+
print(f"* Automation ID: {fetched_automation.id}")
156+
print(f"* Automation name: {fetched_automation.name}")
157+
print(f"* Automation description: {fetched_automation.description}")
158+
159+
# ///////////////////////////////////////////////////////
160+
# // E X E C U T I O N S //
161+
# ///////////////////////////////////////////////////////
162+
163+
# trigger an automation execution
164+
created_execution = automation_api.create_volume_execution(
165+
project_id=project_id,
166+
region=region,
167+
automation_id=str(volume_automation.id),
168+
)
169+
print("\n\nTriggered volume automation execution:")
170+
print(f"* Execution ID: {created_execution.id}")
171+
print(f"* Execution status: {created_execution.status}")
172+
173+
# wait for the automation execution to complete
174+
while str(created_execution.status).upper() in ["PENDING", "RUNNING"]:
175+
print("* Waiting for automation execution to complete ...")
176+
time.sleep(2)
177+
created_execution = automation_api.get_volume_execution(
178+
project_id=project_id,
179+
region=region,
180+
automation_id=str(volume_automation.id),
181+
execution_id=str(created_execution.id),
182+
)
183+
print("* Automation execution completed")
184+
185+
# list all executions of a specific volume automation
186+
list_executions = automation_api.list_volume_executions(
187+
project_id=project_id,
188+
region=region,
189+
automation_id=str(volume_automation.id),
190+
)
191+
print("\n\nListing executions of the volume automation:")
192+
if list_executions.items:
193+
for execution in list_executions.items:
194+
print(f"* Execution ID: {execution.id}")
195+
196+
# ///////////////////////////////////////////////////////
197+
# // D E L E T I O N //
198+
# ///////////////////////////////////////////////////////
199+
200+
# trigger deletion of the created volume automation
201+
print("\n\nDeleting created volume automation")
202+
automation_api.delete_volume_automation(
203+
project_id=project_id,
204+
region=region,
205+
automation_id=str(volume_automation.id),
206+
)
207+
print(f'* Successfully deleted automation with ID "{volume_automation.id}"')
208+
209+
except Exception as e:
210+
print(f"Exception when calling AutomationApi: {e}", file=sys.stderr)
211+
212+
213+
if __name__ == "__main__":
214+
main()

‎services/alb/CHANGELOG.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
## v0.13.0
2+
- **Feature:** Add `ip_block_list_name` field to `LoadbalancerOptionAccessControl` model
3+
14
## v0.12.0
25
- **Feature:** Add new enum values `TYPE_FIP_NOT_FOUND`, `TYPE_IP_EXHAUSTED`, `TYPE_DNS_NOT_CONFIGURED` and `TYPE_VM_PORT_NOT_CONFIGURED` to `LoadBalancerError` model
36

‎services/alb/oas_commit‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
1deab1542e767cd08525dfd6c2cd0b65b9c923c3
1+
7e7c0c6d141ef436fa9dee1e9724936562b7d6da

‎services/alb/pyproject.toml‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[project]
22
name = "stackit-alb"
3-
version = "v0.12.0"
3+
version = "v0.13.0"
44
description = "Application Load Balancer API"
55
authors = [{ name = "STACKIT Developer Tools", email = "developer-tools@stackit.cloud" }]
66
requires-python = ">=3.10,<4.0"

0 commit comments

Comments
 (0)