From 9d1e62defbd8716302b34b3258b680772f6c2311 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ville=20Skytt=C3=A4?= Date: Wed, 10 Sep 2025 13:20:12 +0300 Subject: [PATCH] refactor: remove support for discontinued non-managed object storage MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ville Välimäki <110451292+villevsv-upcloud@users.noreply.github.com> --- CHANGELOG.md | 4 + docs/index.md | 1 - docs/object_storage-mixin.md | 80 ----------- test/json_data/object-storage.json | 28 ---- ..._0608edc4-d4a3-4b01-abe4-e147bd7ffe45.json | 12 -- ..._06b0e4fc-d74b-455e-a373-60cd6ca84022.json | 12 -- ...-455e-a373-60cd6ca84022_stats_network.json | 26 ---- test/json_data/object-storage_post.json | 14 -- test/test_object_storage.py | 78 ---------- upcloud_api/__init__.py | 1 - upcloud_api/cloud_manager/__init__.py | 2 - .../cloud_manager/object_storage_mixin.py | 135 ------------------ upcloud_api/object_storage.py | 23 --- 13 files changed, 4 insertions(+), 412 deletions(-) delete mode 100644 docs/object_storage-mixin.md delete mode 100644 test/json_data/object-storage.json delete mode 100644 test/json_data/object-storage_0608edc4-d4a3-4b01-abe4-e147bd7ffe45.json delete mode 100644 test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022.json delete mode 100644 test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022_stats_network.json delete mode 100644 test/json_data/object-storage_post.json delete mode 100644 test/test_object_storage.py delete mode 100644 upcloud_api/cloud_manager/object_storage_mixin.py delete mode 100644 upcloud_api/object_storage.py diff --git a/CHANGELOG.md b/CHANGELOG.md index a0a0470..4a0993d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Removed + +- Support for discontinued non-managed object storage product. Note: treated as non-breaking change as all users have been migrated to the new managed product + ## [2.8.0] - 2025-08-18 ### Added diff --git a/docs/index.md b/docs/index.md index 1493694..978ff06 100644 --- a/docs/index.md +++ b/docs/index.md @@ -32,7 +32,6 @@ from upcloud_api import Server from upcloud_api import FirewallRule from upcloud_api import Network from upcloud_api import IPAddress -from upcloud_api import ObjectStorage manager = upcloud_api.CloudManager("username", "password") ``` diff --git a/docs/object_storage-mixin.md b/docs/object_storage-mixin.md deleted file mode 100644 index 87c3153..0000000 --- a/docs/object_storage-mixin.md +++ /dev/null @@ -1,80 +0,0 @@ -## About -```python -class ObjectStorageManager(): - """ - Functions for managing Object Storages. Intended to be used as a mixin for CloudManager. - """ -``` -`ObjectStorageManager` is a mixed into `CloudManager` and the following methods are available through it. - -```python -manager = CloudManager("api-username", "password") -manager.method() -``` - -## Methods - -```python -def get_object_storages(self): - """ - List all Object Storage devices on the account or those which the subaccount has permissions. - Returns a list of ObjectStorage objects. - """ -``` - -```python -def create_object_storage(self, zone, access_key, secret_key, size, name=None, description=None): - """ - Used to create a new Object Storage device with a given name, size and location. - Zone, access_key, secret_key and size are mandatory while name and description are optional. - """ -``` - -```python -def modify_object_storage(self, object_storage, access_key=None, secret_key=None, description=None, size=None): - """ - Modify requests can be used to update the details of an Object Storage including description, access_key and secret_key. - Object_storage is mandatory and can be a uuid or a ObjectStorage object. - Access_key, secret_key, description and size are optional. - If passed access_key needs to be provided with secret_key and vice-versa. - """ -``` - -```python -def delete_object_storage(self, object_storage): - """ - Object Storage devices can be deleted using the following API request. - Object_storage is mandatory and can be a uuid or a ObjectStorage object. - """ -``` - -```python -def get_object_storage_network_statistics( - self, - object_storage, - datetime_from, - datetime_to=None, - interval=None, - bucket=[], - filename=[], - method=[], - status=[], - group_by=[], - order_by=[], - limit=None - ): - """ - The network usage of an Object Storage device is metered and can be reviewed using the statistics request. - Object_storage is mandatory and can be a uuid or a ObjectStorage object. - Datetime_from is mandatory and needs to be a Datetime. - Datetime_to is optional and needs to be a Datetime. - Interval is optional and needs to be an integer - Bucket is optional and needs to be a list of bucket name strings - Filename is optional and needs to be a list of filename strings - Method is optional and needs to be a list of method name strings - Status is optional and needs to be a list of http status codes as integers - Group_by is optional and needs to be a list of specified properties as strings - Order_by is optional and needs to be a list of specified properties as strings - Limit is optional and needs to be an integer - """ -``` diff --git a/test/json_data/object-storage.json b/test/json_data/object-storage.json deleted file mode 100644 index 582d918..0000000 --- a/test/json_data/object-storage.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "object_storages": - { - "object_storage": - [ - { - "created": "2020-11-03T15:28:59Z", - "description": "test for python api", - "name": "pyapi-test3", - "size": 250, - "state": "started", - "url": "https://pyapi-test3.fi-hel2.upcloudobjects.com/", - "uuid": "06b0e4fc-d74b-455e-a373-60cd6ca84022", - "zone": "fi-hel2" - }, - { - "created": "2020-11-03T15:16:15Z", - "description": "test-python-api", - "name": "test-python-api", - "size": 250, - "state": "started", - "url": "https://test-python-api.fi-hel2.upcloudobjects.com/", - "uuid": "06f12ae8-8531-44c9-9529-acdd278c7408", - "zone": "fi-hel2" - } - ] - } -} diff --git a/test/json_data/object-storage_0608edc4-d4a3-4b01-abe4-e147bd7ffe45.json b/test/json_data/object-storage_0608edc4-d4a3-4b01-abe4-e147bd7ffe45.json deleted file mode 100644 index ead6268..0000000 --- a/test/json_data/object-storage_0608edc4-d4a3-4b01-abe4-e147bd7ffe45.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "object_storage": { - "created": "2020-11-03T15:28:59Z", - "description": "new description", - "name": "test-os", - "size": 500, - "state": "started", - "url": "https://pyapi-test3.fi-hel2.upcloudobjects.com/", - "uuid": "0608edc4-d4a3-4b01-abe4-e147bd7ffe45", - "zone": "fi-hel2" - } -} diff --git a/test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022.json b/test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022.json deleted file mode 100644 index 7140e75..0000000 --- a/test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "object_storage": { - "created": "2020-11-03T15:28:59Z", - "description": "test for python api", - "name": "pyapi-test3", - "size": 250, - "state": "started", - "url": "https://pyapi-test3.fi-hel2.upcloudobjects.com/", - "uuid": "06b0e4fc-d74b-455e-a373-60cd6ca84022", - "zone": "fi-hel2" - } -} diff --git a/test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022_stats_network.json b/test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022_stats_network.json deleted file mode 100644 index 1e9083e..0000000 --- a/test/json_data/object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022_stats_network.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "stats": - { - "stat": - [ - { - "bytes_received": 1041, - "bytes_transmitted": 3011, - "requests": 5, - "timestamp": "2020-11-03T15:00:00Z" - }, - { - "bytes_received": 583, - "bytes_transmitted": 1296, - "requests": 2, - "timestamp": "2020-11-04T10:00:00Z" - }, - { - "bytes_received": 279, - "bytes_transmitted": 648, - "requests": 1, - "timestamp": "2020-11-04T11:00:00Z" - } - ] - } -} diff --git a/test/json_data/object-storage_post.json b/test/json_data/object-storage_post.json deleted file mode 100644 index 1144095..0000000 --- a/test/json_data/object-storage_post.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "object_storage": - { - "created": "2020-11-05T13:30:21Z", - "description": "for tests", - "name": "test-os", - "size": 250, - "state": "started", - "url": "https://test-os.fi-hel2.upcloudobjects.com/", - "used_space": 0, - "uuid": "0608edc4-d4a3-4b01-abe4-e147bd7ffe45", - "zone": "fi-hel2" - } -} diff --git a/test/test_object_storage.py b/test/test_object_storage.py deleted file mode 100644 index 1601103..0000000 --- a/test/test_object_storage.py +++ /dev/null @@ -1,78 +0,0 @@ -import datetime - -import responses -from conftest import Mock - - -class TestObjectStorage: - @responses.activate - def test_get_object_storages(self, manager): - data = Mock.mock_get('object-storage') - object_storages = manager.get_object_storages() - - for object_storage in object_storages: - assert type(object_storage).__name__ == 'ObjectStorage' - - @responses.activate - def test_create_object_storage(self, manager): - data = Mock.mock_post('object-storage', ignore_data_field=True) - object_storage = manager.create_object_storage( - 'fi-hel2', 'access_key', 'secret_key', 250, 'test-os', 'for tests' - ) - - assert type(object_storage).__name__ == 'ObjectStorage' - assert object_storage.name == 'test-os' - assert object_storage.description == 'for tests' - assert object_storage.zone == 'fi-hel2' - assert object_storage.size == 250 - - @responses.activate - def test_get_object_storage(self, manager): - data = Mock.mock_get('object-storage/06b0e4fc-d74b-455e-a373-60cd6ca84022') - object_storage = manager.get_object_storage('06b0e4fc-d74b-455e-a373-60cd6ca84022') - - assert type(object_storage).__name__ == 'ObjectStorage' - assert object_storage.name == 'pyapi-test3' - assert object_storage.description == 'test for python api' - assert object_storage.zone == 'fi-hel2' - assert object_storage.size == 250 - - @responses.activate - def test_modify_object_storage(self, manager): - data = Mock.mock_patch( - 'object-storage/0608edc4-d4a3-4b01-abe4-e147bd7ffe45', ignore_data_field=True - ) - object_storage = manager.modify_object_storage( - '0608edc4-d4a3-4b01-abe4-e147bd7ffe45', - 'access_key', - 'secret_key', - 'new description', - 500, - ) - - assert type(object_storage).__name__ == 'ObjectStorage' - assert object_storage.name == 'test-os' - assert object_storage.description == 'new description' - assert object_storage.zone == 'fi-hel2' - assert object_storage.size == 500 - - @responses.activate - def test_delete_object_storage(self, manager): - data = Mock.mock_delete('object-storage/0608edc4-d4a3-4b01-abe4-e147bd7ffe45') - res = manager.delete_object_storage('0608edc4-d4a3-4b01-abe4-e147bd7ffe45') - - assert res == {} - - @responses.activate - def test_get_object_storage_network_statistics(self, manager): - Mock.mock_get( - 'object-storage/06b0e4fc-d74b-455e-a373-60cd6ca84022/stats/network/', - response_file='object-storage_06b0e4fc-d74b-455e-a373-60cd6ca84022_stats_network.json', - ) - res = manager.get_object_storage_network_statistics( - object_storage='06b0e4fc-d74b-455e-a373-60cd6ca84022', - datetime_from=datetime.datetime(2020, 11, 3), - ) - - assert 'stats' in res - assert len(res.get('stats').get('stat')) == 3 diff --git a/upcloud_api/__init__.py b/upcloud_api/__init__.py index dbfaaf3..9deb6c9 100644 --- a/upcloud_api/__init__.py +++ b/upcloud_api/__init__.py @@ -28,7 +28,6 @@ LoadBalancerNetwork, ) from upcloud_api.network import Network -from upcloud_api.object_storage import ObjectStorage from upcloud_api.router import Router from upcloud_api.server import Server, ServerNetworkInterface, login_user_block from upcloud_api.server_group import ServerGroup, ServerGroupAffinityPolicy diff --git a/upcloud_api/cloud_manager/__init__.py b/upcloud_api/cloud_manager/__init__.py index dfb1cca..c7b3ea8 100644 --- a/upcloud_api/cloud_manager/__init__.py +++ b/upcloud_api/cloud_manager/__init__.py @@ -4,7 +4,6 @@ from upcloud_api.cloud_manager.ip_address_mixin import IPManager from upcloud_api.cloud_manager.lb_mixin import LoadBalancerManager from upcloud_api.cloud_manager.network_mixin import NetworkManager -from upcloud_api.cloud_manager.object_storage_mixin import ObjectStorageManager from upcloud_api.cloud_manager.server_mixin import ServerManager from upcloud_api.cloud_manager.storage_mixin import StorageManager from upcloud_api.cloud_manager.tag_mixin import TagManager @@ -18,7 +17,6 @@ class CloudManager( IPManager, LoadBalancerManager, NetworkManager, - ObjectStorageManager, ServerManager, StorageManager, TagManager, diff --git a/upcloud_api/cloud_manager/object_storage_mixin.py b/upcloud_api/cloud_manager/object_storage_mixin.py deleted file mode 100644 index 94abc1a..0000000 --- a/upcloud_api/cloud_manager/object_storage_mixin.py +++ /dev/null @@ -1,135 +0,0 @@ -import datetime -from typing import Optional - -from upcloud_api.api import API -from upcloud_api.object_storage import ObjectStorage - - -class ObjectStorageManager: - """ - Functions for managing Object Storages. Intended to be used as a mixin for CloudManager. - """ - - api: API - - def get_object_storages(self): - """ - List all Object Storage devices on the account or those which the sub-account has permissions. - """ - url = '/object-storage' - res = self.api.get_request(url) - object_storages = [ - ObjectStorage(**o_s) for o_s in res['object_storages']['object_storage'] - ] - return object_storages - - def create_object_storage( - self, - zone: str, - access_key: str, - secret_key: str, - size: int, - name: Optional[str] = None, - description: Optional[str] = None, - ) -> ObjectStorage: - """ - Used to create a new Object Storage device with a given name, size and location. - """ - url = '/object-storage' - body = { - 'object_storage': { - 'zone': zone, - 'access_key': access_key, - 'secret_key': secret_key, - 'size': size, - } - } - if name: - body['object_storage']['name'] = name - if description: - body['object_storage']['description'] = description - res = self.api.post_request(url, body) - return ObjectStorage(cloud_manager=self, **res['object_storage']) - - def get_object_storage(self, uuid: str) -> ObjectStorage: - """ - A request to get details about a specific Object Storage device by the given uuid. - """ - url = f'/object-storage/{uuid}' - res = self.api.get_request(url) - return ObjectStorage(cloud_manager=self, **res['object_storage']) - - def modify_object_storage( - self, - object_storage: str, - access_key: Optional[str] = None, - secret_key: Optional[str] = None, - description: Optional[str] = None, - size: Optional[int] = None, - ) -> ObjectStorage: - """ - Modify requests can be used to update the details of an Object Storage including description, access_key and secret_key. - """ - url = f'/object-storage/{object_storage}' - body = {'object_storage': {}} - if access_key and secret_key: - body['object_storage']['access_key'] = access_key - body['object_storage']['secret_key'] = secret_key - elif access_key or secret_key: - raise Exception('Both keys must be provided or none') - - if description: - body['object_storage']['description'] = description - if size: - body['object_storage']['size'] = size - res = self.api.patch_request(url, body) - return ObjectStorage(cloud_manager=self, **res['object_storage']) - - def delete_object_storage(self, object_storage): - """ - Object Storage devices can be deleted using the following API request. - """ - url = f'/object-storage/{object_storage}' - res = self.api.delete_request(url) - return res - - def get_object_storage_network_statistics( - self, - object_storage, - datetime_from: datetime.datetime, - datetime_to: Optional[datetime.datetime] = None, - interval: Optional[int] = None, - bucket: Optional[list[str]] = None, - filename: Optional[list[str]] = None, - method: Optional[list[str]] = None, - status: Optional[list[int]] = None, - group_by: Optional[list[str]] = None, - order_by: Optional[list[str]] = None, - limit: Optional[int] = None, - ): - """ - The network usage of an Object Storage device is metered and can be reviewed using the statistics request. - """ - key_dict = {'from': datetime_from.isoformat(timespec='seconds')} - url = f'/object-storage/{object_storage}/stats/network/?' - - if datetime_to: - key_dict['to'] = datetime_to.isoformat(timespec='seconds') - if interval: - key_dict['interval'] = interval - if bucket: - key_dict['bucket'] = bucket - if filename: - key_dict['filename'] = filename - if method: - key_dict['method'] = method - if status: - key_dict['status'] = status - if group_by: - key_dict['group_by'] = group_by - if order_by: - key_dict['order_by'] = order_by - if limit: - key_dict['limit'] = limit - res = self.api.get_request(url, params=key_dict) - return res diff --git a/upcloud_api/object_storage.py b/upcloud_api/object_storage.py deleted file mode 100644 index 866aefc..0000000 --- a/upcloud_api/object_storage.py +++ /dev/null @@ -1,23 +0,0 @@ -from upcloud_api.upcloud_resource import UpCloudResource - - -class ObjectStorage(UpCloudResource): - """ - Class representation of UpCloud Object Storage. - """ - - ATTRIBUTES = { - 'uuid': None, - 'name': None, - 'description': None, - 'size': None, - 'state': None, - 'url': None, - 'zone': None, - } - - def __str__(self): - """ - String representation of Object Storage. - """ - return self.uuid