Skip to content

Commit 6e1548c

Browse files
Tyler Brittensudorandom
authored andcommitted
Block storage host auth (softlayer#742)
* Cherrypick block-host-auth from iodine53 brand * fixed syntax * Fixed duplicated routes from merge. Changed client references to match 5.1.0 block manager * Fixed bad IP address handling * removed cherrypick comments * Flake8 Cleanup * Flake8 fix * replaced underscores for dashes on CLI * fixed CLI dashes/underscores * Updated authorize/revoke api calls. * Flake8 Fixes * ACTUALLY fixed for Flake8
1 parent 4be0789 commit 6e1548c

7 files changed

Lines changed: 177 additions & 0 deletions

File tree

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"""Block Storage Access Control."""
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
"""Create a block storage snapshot."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
import SoftLayer
6+
from SoftLayer.CLI import environment
7+
from SoftLayer.CLI import exceptions
8+
9+
10+
@click.command()
11+
@click.argument('volume_id')
12+
@click.option('--hardware-id', '-h', multiple=True,
13+
help='The id of one SoftLayer_Hardware to authorize')
14+
@click.option('--virtual-id', '-v', multiple=True,
15+
help='The id of one SoftLayer_Virtual_Guest to authorize')
16+
@click.option('--ip-address-id', '-i', multiple=True,
17+
help='The id of one SoftLayer_Network_Subnet_IpAddress'
18+
' to authorize')
19+
@click.option('--ip-address', multiple=True,
20+
help='An IP address to authorize')
21+
@environment.pass_env
22+
def cli(env, volume_id, hardware_id, virtual_id, ip_address_id, ip_address):
23+
"""Authorizes hosts to access a given volume"""
24+
block_manager = SoftLayer.BlockStorageManager(env.client)
25+
ip_address_id_list = list(ip_address_id)
26+
27+
# Convert actual IP Addresses to their SoftLayer ids
28+
if ip_address is not None:
29+
network_manager = SoftLayer.NetworkManager(env.client)
30+
for ip_address_value in ip_address:
31+
ip_address_object = network_manager.ip_lookup(ip_address_value)
32+
if ip_address_object == "":
33+
click.echo("IP Address not found on your account. " +
34+
"Please confirm IP and try again.")
35+
raise exceptions.ArgumentError('Incorrect IP Address')
36+
else:
37+
ip_address_id_list.append(ip_address_object['id'])
38+
39+
block_manager.authorize_host_to_volume(volume_id,
40+
hardware_id,
41+
virtual_id,
42+
ip_address_id_list)
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
"""Create a block storage snapshot."""
2+
# :license: MIT, see LICENSE for more details.
3+
4+
import click
5+
import SoftLayer
6+
from SoftLayer.CLI import environment
7+
8+
9+
@click.command()
10+
@click.argument('volume_id')
11+
@click.option('--hardware-id', '-h', multiple=True,
12+
help='The id of one SoftLayer_Hardware'
13+
' to revoke authorization')
14+
@click.option('--virtual-id', '-v', multiple=True,
15+
help='The id of one SoftLayer_Virtual_Guest'
16+
' to revoke authorization')
17+
@click.option('--ip_address-id', '-i', multiple=True,
18+
help='The id of one SoftLayer_Network_Subnet_IpAddress'
19+
' to revoke authorization')
20+
@click.option('--ip-address', multiple=True,
21+
help='An IP address to revoke authorization')
22+
@environment.pass_env
23+
def cli(env, volume_id, hardware_id, virtual_id, ip_address_id, ip_address):
24+
"""Revokes authorization for hosts accessing a given volume"""
25+
block_manager = SoftLayer.BlockStorageManager(env.client)
26+
ip_address_id_list = list(ip_address_id)
27+
28+
# Convert actual IP Addresses to their SoftLayer ids
29+
if ip_address is not None:
30+
network_manager = SoftLayer.NetworkManager(env.client)
31+
for ip_address_value in ip_address:
32+
ip_address_object = network_manager.ip_lookup(ip_address_value)
33+
ip_address_id_list.append(ip_address_object['id'])
34+
35+
block_manager.deauthorize_host_to_volume(volume_id,
36+
hardware_id,
37+
virtual_id,
38+
ip_address_id_list)

SoftLayer/CLI/routes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,9 +61,13 @@
6161
('block:volume-detail', 'SoftLayer.CLI.block.detail:cli'),
6262
('block:volume-cancel', 'SoftLayer.CLI.block.cancel:cli'),
6363
('block:volume-order', 'SoftLayer.CLI.block.order:cli'),
64+
6465
('block:snapshot-list', 'SoftLayer.CLI.block.snapshot_list:cli'),
6566
('block:snapshot-delete', 'SoftLayer.CLI.block.snapshot_delete:cli'),
67+
6668
('block:access-list', 'SoftLayer.CLI.block.access_list:cli'),
69+
('block:access-authorize', 'SoftLayer.CLI.block.access.authorize:cli'),
70+
('block:access-revoke', 'SoftLayer.CLI.block.access.revoke:cli'),
6771

6872
('firewall', 'SoftLayer.CLI.firewall'),
6973
('firewall:add', 'SoftLayer.CLI.firewall.add:cli'),

SoftLayer/fixtures/SoftLayer_Network_Storage.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,5 @@
6363
}
6464
getSnapshots = []
6565
deleteObject = True
66+
allowAccessFromHostList = True
67+
removeAccessFromHostList = True

SoftLayer/managers/block.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,80 @@ def get_block_volume_snapshot_list(self, volume_id, **kwargs):
135135
return self.client.call('Network_Storage', 'getSnapshots',
136136
id=volume_id, **kwargs)
137137

138+
def authorize_host_to_volume(self, volume_id,
139+
hardware_ids=None,
140+
virtual_guest_ids=None,
141+
ip_address_ids=None):
142+
"""Authorizes hosts to Block Storage Volumes
143+
144+
:param volume_id: The Volume to authorize hosts to
145+
:param hardware_ids: A List of SoftLayer_Hardware ids
146+
:param virtual_guest_ids: A List of SoftLayer_Virtual_Guest ids
147+
:param ip_address_ids: A List of SoftLayer_Network_Subnet_IpAddress ids
148+
"""
149+
host_templates = []
150+
151+
if hardware_ids is not None:
152+
for hardware_id in hardware_ids:
153+
host_templates.append({
154+
'objectType': 'SoftLayer_Hardware',
155+
'id': hardware_id
156+
})
157+
158+
if virtual_guest_ids is not None:
159+
for virtual_guest_id in virtual_guest_ids:
160+
host_templates.append({
161+
'objectType': 'SoftLayer_Virtual_Guest',
162+
'id': virtual_guest_id
163+
})
164+
165+
if ip_address_ids is not None:
166+
for ip_address_id in ip_address_ids:
167+
host_templates.append({
168+
'objectType': 'SoftLayer_Network_Subnet_IpAddress',
169+
'id': ip_address_id
170+
})
171+
172+
return self.client.call('Network_Storage', 'allowAccessFromHostList',
173+
host_templates, id=volume_id)
174+
175+
def deauthorize_host_to_volume(self, volume_id,
176+
hardware_ids=None,
177+
virtual_guest_ids=None,
178+
ip_address_ids=None):
179+
"""Revokes authorization of hosts to Block Storage Volumes
180+
181+
:param volume_id: The Volume to deauthorize hosts to
182+
:param hardware_ids: A List of SoftLayer_Hardware ids
183+
:param virtual_guest_ids: A List of SoftLayer_Virtual_Guest ids
184+
:param ip_address_ids: A List of SoftLayer_Network_Subnet_IpAddress ids
185+
"""
186+
host_templates = []
187+
188+
if hardware_ids is not None:
189+
for hardware_id in hardware_ids:
190+
host_templates.append({
191+
'objectType': 'SoftLayer_Hardware',
192+
'id': hardware_id
193+
})
194+
195+
if virtual_guest_ids is not None:
196+
for virtual_guest_id in virtual_guest_ids:
197+
host_templates.append({
198+
'objectType': 'SoftLayer_Virtual_Guest',
199+
'id': virtual_guest_id
200+
})
201+
202+
if ip_address_ids is not None:
203+
for ip_address_id in ip_address_ids:
204+
host_templates.append({
205+
'objectType': 'SoftLayer_Network_Subnet_IpAddress',
206+
'id': ip_address_id
207+
})
208+
209+
return self.client.call('Network_Storage', 'removeAccessFromHostList',
210+
host_templates, id=volume_id)
211+
138212
def delete_snapshot(self, snapshot_id):
139213
"""Deletes the specified snapshot object.
140214

tests/managers/block_tests.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,3 +210,19 @@ def test_order_block_volume_endurance(self):
210210
'setupFee': '1'}],
211211
},
212212
)
213+
214+
def test_authorize_host_to_volume(self):
215+
result = self.block.authorize_host_to_volume(50,
216+
hardware_ids=[100],
217+
virtual_guest_ids=[200],
218+
ip_address_ids=[300])
219+
self.assertEqual(fixtures.SoftLayer_Network_Storage.
220+
allowAccessFromHostList, result)
221+
222+
def test_deauthorize_host_to_volume(self):
223+
result = self.block.authorize_host_to_volume(50,
224+
hardware_ids=[100],
225+
virtual_guest_ids=[200],
226+
ip_address_ids=[300])
227+
self.assertEqual(fixtures.SoftLayer_Network_Storage.
228+
removeAccessFromHostList, result)

0 commit comments

Comments
 (0)