Skip to content

Commit fc2b8d4

Browse files
authored
Ronerez/s3bucket (#206)
1 parent 8d25350 commit fc2b8d4

File tree

8 files changed

+362
-1
lines changed

8 files changed

+362
-1
lines changed

cterasdk/core/cloudfs.py

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class CloudFS(BaseCommand):
1818
:ivar cterasdk.core.cloudfs.CloudDrives drives: Object holding Cloud Drive Folders APIs
1919
:ivar cterasdk.core.cloudfs.Backups backups: Object holding Backup Folders APIs
2020
:ivar cterasdk.core.cloudfs.Zones zones: Object holding Zones APIs
21+
:ivar cterasdk.core.cloudfs.Exports exports: Object holding Bucket Exports APIs
2122
"""
2223

2324
def __init__(self, portal):
@@ -26,6 +27,7 @@ def __init__(self, portal):
2627
self.drives = CloudDrives(self._portal)
2728
self.backups = Backups(self._portal)
2829
self.zones = Zones(self._portal)
30+
self.exports = Exports(self._portal)
2931

3032

3133
class FolderGroups(BaseCommand):
@@ -192,7 +194,7 @@ def modify(self, current_name, owner, new_name=None, new_owner=None, new_group=N
192194
if new_name:
193195
param.name = new_name
194196
if new_owner:
195-
param.owner = self._portal.users.get(owner, ['baseObjectRef']).baseObjectRef
197+
param.owner = self._portal.users.get(new_owner, ['baseObjectRef']).baseObjectRef
196198
if new_group:
197199
param.group = self._portal.cloudfs.groups.get(new_group, include=['baseObjectRef']).baseObjectRef
198200
if description:
@@ -533,3 +535,77 @@ def _zone_param(name, policy_type, description=None, zid=None):
533535
param.delta.devicesDelta.added = []
534536
param.delta.devicesDelta.removed = []
535537
return param
538+
539+
540+
class Exports(BaseCommand):
541+
""" S3 Exports APIs """
542+
543+
def get(self, name):
544+
"""
545+
Get Buckets
546+
547+
:param str name: Bucket name
548+
"""
549+
return self._portal.get(f'/buckets/{name}')
550+
551+
def get_endpoint(self, name):
552+
"""
553+
Get Endpoint
554+
555+
:param str name: Bucket name
556+
:returns: Bucket endpoint
557+
:rtype: str
558+
"""
559+
return self.get(name).url
560+
561+
def all(self):
562+
"""
563+
List Buckets
564+
"""
565+
param = query.QueryParamBuilder().startFrom(0).countLimit(25).orFilter(True).build()
566+
return query.iterator(self._portal, '/buckets', param)
567+
568+
def add(self, name, drive_name, drive_owner, description=None):
569+
"""
570+
Add Bucket
571+
572+
:param str name: Bucket name
573+
:param str drive_name: Cloud Drive Folder name
574+
:param str drive_owner: Cloud Drive Folder owner
575+
:param str,optional description: Bucket description
576+
"""
577+
param = Object()
578+
param._classname = 'Bucket' # pylint: disable=protected-access
579+
param.description = description
580+
param.name = name
581+
param.cloudDrive = self._portal.cloudfs.drives.find(drive_name, drive_owner, include=['baseObjectRef']).baseObjectRef
582+
logging.getLogger().info('Adding Bucket. %s', {'name': name})
583+
response = self._portal.add('/buckets', param)
584+
logging.getLogger().info('Bucket Added. %s', {'name': name})
585+
return response
586+
587+
def modify(self, name, description):
588+
"""
589+
Modify Bucket
590+
591+
:param str name: Bucket name
592+
:param str description: Bucket description
593+
"""
594+
595+
bucket = self.get(name)
596+
bucket.description = description
597+
logging.getLogger().info("Modifying Bucket. %s", {'name': name})
598+
response = self._portal.put(f'/buckets/{name}', bucket)
599+
logging.getLogger().info("Bucket modified. %s", {'name': name})
600+
return response
601+
602+
def delete(self, name):
603+
"""
604+
Remove Bucket
605+
606+
:param str name: Bucket name
607+
"""
608+
logging.getLogger().info('Deleting Bucket. %s', {'name': name})
609+
response = self._portal.delete(f'/buckets/{name}')
610+
logging.getLogger().info('Bucket deleted. %s', {'name': name})
611+
return response

cterasdk/core/credentials.py

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import logging
2+
3+
from .types import UserAccount
4+
from .base_command import BaseCommand
5+
6+
7+
class Credentials(BaseCommand):
8+
"""
9+
Portal Credential Management APIs
10+
11+
:ivar cterasdk.core.credentials.S3 s3: Object holding the Portal S3 Credential Management APIs.
12+
"""
13+
14+
def __init__(self, portal):
15+
super().__init__(portal)
16+
self.s3 = S3(self._portal)
17+
18+
19+
class S3(BaseCommand):
20+
"""S3 Credential Management APIs"""
21+
22+
def _user_account(self, user_account=None):
23+
return user_account if user_account else UserAccount(self._portal.session().user.name)
24+
25+
def all(self, user_account=None):
26+
"""
27+
List Credentials
28+
29+
:param cterasdk.core.types.UserAccount,optional user_account: User account
30+
"""
31+
user_account = self._user_account(user_account)
32+
param = self._portal.users.get(user_account, ['uid']).uid
33+
logging.getLogger().info('Listing Credentials. %s', {'user': str(user_account)})
34+
return self._portal.execute('', 'getApiKeys', param)
35+
36+
def create(self, user_account=None):
37+
"""
38+
Create Credential
39+
40+
:param cterasdk.core.types.UserAccount,optional user_account: User account
41+
"""
42+
user_account = self._user_account(user_account)
43+
param = self._portal.users.get(user_account, ['uid']).uid
44+
logging.getLogger().info('Creating Credential. %s', {'type': 's3', 'user': str(user_account)})
45+
response = self._portal.execute('', 'createApiKey', param)
46+
logging.getLogger().info('Credetial created. %s', {'type': 's3', 'user': str(user_account)})
47+
return response
48+
49+
def delete(self, access_key_id, user_account=None):
50+
"""
51+
Delete Credential
52+
53+
:param str access_key_id: Access Key ID
54+
:param cterasdk.core.types.UserAccount,optional user_account: User account
55+
"""
56+
user_account = self._user_account(user_account)
57+
for key in self.all(user_account):
58+
if key.accessKey == access_key_id:
59+
logging.getLogger().info('Deleting Credential. %s', {'type': 's3'})
60+
response = self._portal.execute('', 'deleteApiKey', key.uid)
61+
logging.getLogger().info('Credetial deleted. %s', {'type': 's3'})
62+
return response
63+
logging.getLogger().warning('Could not find access key. %s', {'key': access_key_id})
64+
return None

cterasdk/core/users.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,16 @@
1111
class Users(BaseCommand):
1212
"""
1313
Portal User Management APIs
14+
15+
:ivar cterasdk.core.credentials.Credentials credentials: Object holding Portal User Credential Management APIs.
1416
"""
1517

1618
default = ['name']
1719

20+
def __init__(self, portal):
21+
super().__init__(portal)
22+
self.credentials = Credentials(self._portal)
23+
1824
def _get_entire_object(self, user_account):
1925
ref = f'/users/{user_account.name}' if user_account.is_local \
2026
else f'/domains/{user_account.directory}/adUsers/{user_account.name}'
@@ -169,3 +175,46 @@ def delete(self, user):
169175
logging.getLogger().info('User deleted. %s', {'user': str(user)})
170176

171177
return response
178+
179+
180+
class Credentials(BaseCommand):
181+
"""
182+
Portal Credential Management APIs
183+
184+
:ivar cterasdk.core.credentials.S3 s3: Object holding the Portal User S3 Credential Management APIs.
185+
"""
186+
187+
def __init__(self, portal):
188+
super().__init__(portal)
189+
self.s3 = S3(self._portal)
190+
191+
192+
class S3(BaseCommand):
193+
"""
194+
S3 Credential Management APIs
195+
"""
196+
197+
def all(self, user_account):
198+
"""
199+
List Credentials
200+
201+
:param cterasdk.core.types.UserAccount user_account: User account
202+
"""
203+
return self._portal.credentials.s3.all(user_account)
204+
205+
def create(self, user_account):
206+
"""
207+
Create Credential
208+
209+
:param cterasdk.core.types.UserAccount user_account: User account
210+
"""
211+
return self._portal.credentials.s3.create(user_account)
212+
213+
def delete(self, access_key_id, user_account):
214+
"""
215+
Delete Credential
216+
217+
:param str access_key_id: Access Key ID
218+
:param cterasdk.core.types.UserAccount user_account: User account
219+
"""
220+
return self._portal.credentials.s3.delete(access_key_id, user_account)

cterasdk/object/Portal.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
from ..core import reports
1818
from ..core import servers
1919
from ..core import devices
20+
from ..core import credentials
2021
from ..core import session
2122
from ..core import storage_classes
2223
from ..core import domains
@@ -84,6 +85,7 @@ def __init__(self, host, port, https):
8485
self.roles = roles.Roles(self)
8586
self.settings = settings.Settings(self)
8687
self.storage_classes = storage_classes.StorageClasses(self)
88+
self.credentials = credentials.Credentials(self)
8789
self.tasks = taskmgr.Tasks(self)
8890
self.templates = templates.Templates(self)
8991
self.firmwares = firmwares.Firmwares(self)
@@ -133,6 +135,7 @@ def _omit_fields(self):
133135
'logs',
134136
'roles',
135137
'settings',
138+
'credentials',
136139
'tasks',
137140
'templates',
138141
'firmwares'

docs/source/user_guides/Portal/EndUser.rst

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,3 +38,32 @@ Logging in
3838
.. code-block:: python
3939
4040
user.logout()
41+
42+
43+
Managing S3 Credentials
44+
=======================
45+
.. automethod:: cterasdk.core.credentials.S3.all
46+
:noindex:
47+
48+
.. code-block:: python
49+
50+
"""List all S3 credentials"""
51+
for credential in user.credentials.s3.all():
52+
print(credential.accessKey, credential.activated)
53+
54+
.. automethod:: cterasdk.core.credentials.S3.create
55+
:noindex:
56+
57+
.. code-block:: python
58+
59+
"""Create an S3 credential"""
60+
credential = user.credentials.s3.create()
61+
62+
.. automethod:: cterasdk.core.credentials.S3.delete
63+
:noindex:
64+
65+
.. code-block:: python
66+
67+
"""Delete an S3 credentials"""
68+
access_key_id = 'ABCDEFGHIJKLMOP'
69+
user.credentials.s3.delete(access_key_id)

docs/source/user_guides/Portal/GlobalAdmin.rst

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1039,6 +1039,37 @@ Directory Services
10391039
admin.directoryservice.disconnect()
10401040
10411041
1042+
Credentials
1043+
-----------
1044+
.. automethod:: cterasdk.core.credentials.S3.all
1045+
:noindex:
1046+
1047+
.. code-block:: python
1048+
1049+
"""List all of 'jsmith@demo.local' S3 credentials"""
1050+
jsmith = portal_types.UserAccount('jsmith', 'demo.local')
1051+
for credential in user.credentials.s3.all(jsmith):
1052+
print(credential.accessKey, credential.activated)
1053+
1054+
.. automethod:: cterasdk.core.credentials.S3.create
1055+
:noindex:
1056+
1057+
.. code-block:: python
1058+
1059+
"""Create an S3 credential for a service account"""
1060+
service_account = portal_types.UserAccount('service_account')
1061+
credential = user.credentials.s3.create(service_account)
1062+
1063+
.. automethod:: cterasdk.core.credentials.S3.delete
1064+
:noindex:
1065+
1066+
.. code-block:: python
1067+
1068+
"""Delete an S3 credentials associated with a user account"""
1069+
user_account = portal_types.UserAccount('jsmith', 'demo.local')
1070+
access_key_id = 'ABCDEFGHIJKLMOP'
1071+
user.credentials.s3.delete(access_key_id, user_account)
1072+
10421073
Groups
10431074
------
10441075

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
# pylint: disable=protected-access
2+
import munch
3+
4+
from cterasdk.core.types import UserAccount
5+
from cterasdk.core import credentials
6+
from tests.ut import base_core
7+
8+
9+
class TestCoreCredentialsS3(base_core.BaseCoreTest):
10+
11+
def setUp(self):
12+
super().setUp()
13+
self._user_account = UserAccount('user')
14+
self._uid = 1500
15+
self._access_key_id = 'ABCD'
16+
self._access_key_uid = 2500
17+
self._mock_get_user_uid = self.patch_call("cterasdk.core.users.Users.get")
18+
self._mock_get_user_uid.return_value = munch.Munch({'uid': self._uid})
19+
20+
def test_list_s3_credentials(self):
21+
execute_response = 'Success'
22+
self._init_global_admin(execute_response=execute_response)
23+
ret = credentials.S3(self._global_admin).all(self._user_account)
24+
self._mock_get_user_uid.assert_called_once_with(self._user_account, ['uid'])
25+
self._global_admin.execute.assert_called_once_with('', 'getApiKeys', self._uid)
26+
self.assertEqual(ret, execute_response)
27+
28+
def test_create_s3_credential(self):
29+
execute_response = 'Success'
30+
self._init_global_admin(execute_response=execute_response)
31+
ret = credentials.S3(self._global_admin).create(self._user_account)
32+
self._mock_get_user_uid.assert_called_once_with(self._user_account, ['uid'])
33+
self._global_admin.execute.assert_called_once_with('', 'createApiKey', self._uid)
34+
self.assertEqual(ret, execute_response)
35+
36+
def test_delete_s3_credential_success(self):
37+
execute_response = 'Success'
38+
mock_get_s3_credentials = self.patch_call("cterasdk.core.credentials.S3.all")
39+
mock_get_s3_credentials.return_value = [munch.Munch({'accessKey': self._access_key_id, 'uid': self._access_key_uid})]
40+
self._init_global_admin(execute_response=execute_response)
41+
ret = credentials.S3(self._global_admin).delete(self._access_key_id, self._user_account)
42+
mock_get_s3_credentials.assert_called_once_with(self._user_account)
43+
self._global_admin.execute.assert_called_once_with('', 'deleteApiKey', self._access_key_uid)
44+
self.assertEqual(ret, execute_response)
45+
46+
def test_delete_s3_credential_not_found(self):
47+
self._init_global_admin()
48+
mock_get_s3_credentials = self.patch_call("cterasdk.core.credentials.S3.all")
49+
mock_get_s3_credentials.return_value = [munch.Munch({'accessKey': self._access_key_id, 'uid': self._access_key_uid})]
50+
ret = credentials.S3(self._global_admin).delete('not_found', self._user_account)
51+
mock_get_s3_credentials.assert_called_once_with(self._user_account)
52+
self._global_admin.execute.assert_not_called()
53+
self.assertEqual(ret, None)

0 commit comments

Comments
 (0)