Skip to content

Commit 1b581fa

Browse files
author
Fernando Ojeda
committed
Fix object storage credentials.
1 parent cfab07e commit 1b581fa

File tree

10 files changed

+377
-0
lines changed

10 files changed

+377
-0
lines changed
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""Manages Object Storage S3 Credentials."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import importlib
5+
import os
6+
7+
import click
8+
9+
CONTEXT = {'help_option_names': ['-h', '--help'],
10+
'max_content_width': 999}
11+
12+
13+
class CapacityCommands(click.MultiCommand):
14+
"""Loads module for object storage S3 credentials related commands."""
15+
16+
def __init__(self, **attrs):
17+
click.MultiCommand.__init__(self, **attrs)
18+
self.path = os.path.dirname(__file__)
19+
20+
def list_commands(self, ctx):
21+
"""List all sub-commands."""
22+
commands = []
23+
for filename in os.listdir(self.path):
24+
if filename == '__init__.py':
25+
continue
26+
if filename.endswith('.py'):
27+
commands.append(filename[:-3].replace("_", "-"))
28+
commands.sort()
29+
return commands
30+
31+
def get_command(self, ctx, cmd_name):
32+
"""Get command for click."""
33+
path = "%s.%s" % (__name__, cmd_name)
34+
path = path.replace("-", "_")
35+
module = importlib.import_module(path)
36+
return getattr(module, 'cli')
37+
38+
39+
# Required to get the sub-sub-sub command to work.
40+
@click.group(cls=CapacityCommands, context_settings=CONTEXT)
41+
def cli():
42+
"""Base command for all object storage credentials S3 related concerns"""
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
"""Create credentials for an IBM Cloud Object Storage Account."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment
8+
from SoftLayer.CLI import formatting
9+
10+
11+
@click.command()
12+
@click.argument('identifier')
13+
@environment.pass_env
14+
def cli(env, identifier):
15+
"""Create credentials for an IBM Cloud Object Storage Account"""
16+
17+
mgr = SoftLayer.ObjectStorageManager(env.client)
18+
credential = mgr.create_credential(identifier)
19+
table = formatting.Table(['id', 'password', 'username', 'type_name'])
20+
table.sortby = 'id'
21+
table.add_row([
22+
credential['id'],
23+
credential['password'],
24+
credential['username'],
25+
credential['type']['name']
26+
])
27+
28+
env.fout(table)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
"""Delete the credential of an Object Storage Account."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment, exceptions
8+
9+
10+
@click.command()
11+
@click.argument('identifier')
12+
@click.option('--credential_id', '-id', type=click.INT,
13+
help="This is the credential id associated with the volume")
14+
@environment.pass_env
15+
def cli(env, identifier, credential_id):
16+
"""Delete the credential of an Object Storage Account."""
17+
18+
mgr = SoftLayer.ObjectStorageManager(env.client)
19+
credential = mgr.delete_credential(identifier, credential_id=credential_id)
20+
21+
if credential:
22+
env.fout("The credential was deleted successful")
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
""" Credential limits for this IBM Cloud Object Storage account."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment
8+
from SoftLayer.CLI import formatting
9+
10+
11+
@click.command()
12+
@click.argument('identifier')
13+
@environment.pass_env
14+
def cli(env, identifier):
15+
""" Credential limits for this IBM Cloud Object Storage account."""
16+
17+
mgr = SoftLayer.ObjectStorageManager(env.client)
18+
limit = mgr.limit_credential(identifier)
19+
table = formatting.Table(['limit'])
20+
table.add_row([
21+
limit,
22+
])
23+
24+
env.fout(table)
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
"""Retrieve credentials used for generating an AWS signature. Max of 2."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
6+
import SoftLayer
7+
from SoftLayer.CLI import environment
8+
from SoftLayer.CLI import formatting
9+
10+
11+
@click.command()
12+
@click.argument('identifier')
13+
@environment.pass_env
14+
def cli(env, identifier):
15+
"""Retrieve credentials used for generating an AWS signature. Max of 2."""
16+
17+
mgr = SoftLayer.ObjectStorageManager(env.client)
18+
list = mgr.list_credential(identifier)
19+
table = formatting.Table(['id', 'password', 'username', 'type_name'])
20+
21+
for credential in list:
22+
table.add_row([
23+
credential['id'],
24+
credential['password'],
25+
credential['username'],
26+
credential['type']['name']
27+
])
28+
29+
env.fout(table)

SoftLayer/CLI/routes.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,8 @@
199199
'SoftLayer.CLI.object_storage.list_accounts:cli'),
200200
('object-storage:endpoints',
201201
'SoftLayer.CLI.object_storage.list_endpoints:cli'),
202+
('object-storage:credential',
203+
'SoftLayer.CLI.object_storage.credential:cli'),
202204

203205
('order', 'SoftLayer.CLI.order'),
204206
('order:category-list', 'SoftLayer.CLI.order.category_list:cli'),
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
credentialCreate = {
2+
"accountId": "12345",
3+
"createDate": "2019-04-05T13:25:25-06:00",
4+
"id": 11111,
5+
"password": "nwUEUsx6PiEoN0B1Xe9z9hUCyXMkAFhDOjHqYJva",
6+
"username": "XfHhBNBPlPdlWyaPPJAI",
7+
"type": {
8+
"description": "A credential for generating S3 Compatible Signatures.",
9+
"keyName": "S3_COMPATIBLE_SIGNATURE",
10+
"name": "S3 Compatible Signature"
11+
}
12+
}
13+
14+
getCredentials = [
15+
{
16+
"accountId": "12345",
17+
"createDate": "2019-04-05T13:25:25-06:00",
18+
"id": 11111,
19+
"password": "nwUEUsx6PiEoN0B1Xe9z9hUCyXMkAFhDOjHqYJva",
20+
"username": "XfHhBNBPlPdlWyaPPJAI",
21+
"type": {
22+
"description": "A credential for generating S3 Compatible Signatures.",
23+
"keyName": "S3_COMPATIBLE_SIGNATURE",
24+
"name": "S3 Compatible Signature"
25+
}
26+
},
27+
{
28+
"accountId": "12345",
29+
"createDate": "2019-04-05T13:25:25-06:00",
30+
"id": 11111,
31+
"password": "nwUEUsx6PiEoN0B1Xe9z9hUCyXMkAFhDOjHqYJva",
32+
"username": "XfHhBNBPlPdlWyaPPJAI",
33+
"type": {
34+
"description": "A credential for generating S3 Compatible Signatures.",
35+
"keyName": "S3_COMPATIBLE_SIGNATURE",
36+
"name": "S3 Compatible Signature"
37+
}
38+
}
39+
]

SoftLayer/managers/object_storage.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,47 @@ def list_endpoints(self):
5252
})
5353

5454
return endpoints
55+
56+
def create_credential(self, identifier):
57+
"""Create object storage credential.
58+
59+
:param int identifier: The object storage account identifier.
60+
61+
"""
62+
63+
return self.client.call('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'credentialCreate',
64+
id=identifier)
65+
66+
def delete_credential(self, identifier, credential_id=None):
67+
"""Delete the object storage credential.
68+
69+
:param int id: The object storage account identifier.
70+
:param int credential_id: The credential id to be deleted.
71+
72+
"""
73+
credential = {
74+
'id': credential_id
75+
}
76+
77+
return self.client.call('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'credentialDelete',
78+
credential, id=identifier)
79+
80+
def limit_credential(self, identifier):
81+
"""Limit object storage credentials.
82+
83+
:param int identifier: The object storage account identifier.
84+
85+
"""
86+
87+
return self.client.call('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'getCredentialLimit',
88+
id=identifier)
89+
90+
def list_credential(self, identifier):
91+
"""List the object storage credentials.
92+
93+
:param int identifier: The object storage account identifier.
94+
95+
"""
96+
97+
return self.client.call('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'getCredentials',
98+
id=identifier)

tests/CLI/modules/object_storage_tests.py

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,73 @@ def test_list_endpoints(self):
3737
[{'datacenter': 'dal05',
3838
'private': 'https://dal05/auth/v1.0/',
3939
'public': 'https://dal05/auth/v1.0/'}])
40+
41+
def test_create_credential(self):
42+
accounts = self.set_mock('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'credentialCreate')
43+
accounts.return_value = {
44+
"accountId": "12345",
45+
"createDate": "2019-04-05T13:25:25-06:00",
46+
"id": 11111,
47+
"password": "nwUEUsx6PiEoN0B1Xe9z9hUCy",
48+
"username": "XfHhBNBPlPdl",
49+
"type": {
50+
"description": "A credential for generating S3 Compatible Signatures.",
51+
"keyName": "S3_COMPATIBLE_SIGNATURE",
52+
"name": "S3 Compatible Signature"
53+
}
54+
}
55+
56+
result = self.run_command(['object-storage', 'credential', 'create', '100'])
57+
58+
self.assert_no_fail(result)
59+
self.assertEqual(json.loads(result.output),
60+
[{'id': 11111,
61+
'password': 'nwUEUsx6PiEoN0B1Xe9z9hUCy',
62+
'type_name': 'S3 Compatible Signature',
63+
'username': 'XfHhBNBPlPdl'}]
64+
)
65+
66+
def test_delete_credential(self):
67+
accounts = self.set_mock('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'credentialDelete')
68+
accounts.return_value = True
69+
70+
result = self.run_command(['object-storage', 'credential', 'delete', '-id=100', '100'])
71+
72+
self.assert_no_fail(result)
73+
self.assertEqual(json.loads(result.output),
74+
'The credential was deleted successful'
75+
)
76+
77+
def test_limit_credential(self):
78+
accounts = self.set_mock('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'getCredentialLimit')
79+
accounts.return_value = 2
80+
81+
result = self.run_command(['object-storage', 'credential', 'limit', '100'])
82+
83+
self.assert_no_fail(result)
84+
self.assertEqual(json.loads(result.output), [{'limit': 2}])
85+
86+
def test_list_credential(self):
87+
accounts = self.set_mock('SoftLayer_Network_Storage_Hub_Cleversafe_Account', 'getCredentials')
88+
accounts.return_value = [{'id': 1103123,
89+
'password': 'nwUEUsx6PiEoN0B1Xe9z9hUCyXM',
90+
'type': {'name': 'S3 Compatible Signature'},
91+
'username': 'XfHhBNBPlPdlWya'},
92+
{'id': 1103333,
93+
'password': 'nwUEUsx6PiEoN0B1Xe9z9',
94+
'type': {'name': 'S3 Compatible Signature'},
95+
'username': 'XfHhBNBPlPd'}]
96+
97+
result = self.run_command(['object-storage', 'credential', 'list', '100'])
98+
99+
self.assert_no_fail(result)
100+
print(json.loads(result.output))
101+
self.assertEqual(json.loads(result.output),
102+
[{'id': 1103123,
103+
'password': 'nwUEUsx6PiEoN0B1Xe9z9hUCyXM',
104+
'type_name': 'S3 Compatible Signature',
105+
'username': 'XfHhBNBPlPdlWya'},
106+
{'id': 1103333,
107+
'password': 'nwUEUsx6PiEoN0B1Xe9z9',
108+
'type_name': 'S3 Compatible Signature',
109+
'username': 'XfHhBNBPlPd'}])

0 commit comments

Comments
 (0)