Skip to content

Commit f4cc9fa

Browse files
authored
Merge branch 'softlayer:master' into master
2 parents e938d71 + dae2ec7 commit f4cc9fa

File tree

8 files changed

+353
-39
lines changed

8 files changed

+353
-39
lines changed

README.rst

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,11 +153,16 @@ If you are using the library directly in python, you can do something like this.
153153
154154
System Requirements
155155
-------------------
156-
* Python 3.5, 3.6, 3.7, 3.8, or 3.9.
156+
* Python 3.8, 3.9, or 3.10.
157157
* A valid SoftLayer API username and key.
158158
* A connection to SoftLayer's private network is required to use
159159
our private network API endpoints.
160160

161+
Python 3.6 Support
162+
------------------
163+
As of version 6.0.0 SoftLayer-Python will no longer support python3.6, which is `End of Life as of 2022 <https://endoflife.date/python>`_.
164+
If you cannot install python 3.8+ for some reason, you will need to use a version of softlayer-python <= 6.0.0
165+
161166
Python 2.7 Support
162167
------------------
163168
As of version 5.8.0 SoftLayer-Python will no longer support python2.7, which is `End Of Life as of 2020 <https://www.python.org/dev/peps/pep-0373/>`_ .
@@ -167,12 +172,15 @@ If you cannot install python 3.6+ for some reason, you will need to use a versio
167172

168173
Python Packages
169174
---------------
170-
* prettytable >= 2.0.0
171-
* click >= 7
175+
* prettytable >= 2.5.0
176+
* click >= 8.0.4
172177
* requests >= 2.20.0
173178
* prompt_toolkit >= 2
174179
* pygments >= 2.0.0
175180
* urllib3 >= 1.24
181+
* rich == 12.3.0
182+
183+
*NOTE* If `ptable` (not prettytable) is installed, this will cause issues rendering tables.
176184

177185
Copyright
178186
---------

SoftLayer/CLI/firewall/detail.py

Lines changed: 62 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,31 +12,77 @@
1212

1313
@click.command(cls=SoftLayer.CLI.command.SLCommand, )
1414
@click.argument('identifier')
15+
@click.option('--credentials', type=click.BOOL,
16+
help="Display FortiGate username and FortiGate password to multi vlans.")
1517
@environment.pass_env
16-
def cli(env, identifier):
17-
"""Detail firewall."""
18+
def cli(env, identifier, credentials):
19+
"""Detail firewall.
20+
21+
EXAMPLES:
22+
23+
slcli firewall detail vs:12345
24+
25+
slcli firewall detail --credentials true multiVlan:456789
26+
"""
1827

1928
mgr = SoftLayer.FirewallManager(env.client)
2029

2130
firewall_type, firewall_id = firewall.parse_id(identifier)
22-
_firewall = mgr.get_instance(firewall_id)
2331

24-
table = formatting.KeyValueTable(['name', 'value'])
25-
table.align['name'] = 'r'
26-
table.align['value'] = 'l'
32+
if firewall_type in ('vs', 'server', 'vlan', 'multiVlan'):
33+
34+
if firewall_type == 'vlan':
35+
_firewall = mgr.get_instance(firewall_id)
36+
37+
table = formatting.KeyValueTable(['name', 'value'])
38+
table.align['name'] = 'r'
39+
table.align['value'] = 'l'
40+
41+
table.add_row(['id', _firewall.get('id')])
42+
table.add_row(['primaryIpAddress', _firewall.get('primaryIpAddress')])
43+
table.add_row(['datacenter', utils.lookup(_firewall, 'datacenter', 'longName')])
44+
table.add_row(['networkVlan', utils.lookup(_firewall, 'networkVlan', 'name')])
45+
table.add_row(['networkVlaniD', utils.lookup(_firewall, 'networkVlan', 'id')])
46+
47+
rules = mgr.get_dedicated_fwl_rules(firewall_id)
48+
table.add_row(['rules', get_rules_table(rules)])
49+
50+
if firewall_type == 'multiVlan':
51+
_firewall = mgr.get_instance(firewall_id)
52+
53+
table = formatting.KeyValueTable(['name', 'value'])
54+
table.align['name'] = 'r'
55+
table.align['value'] = 'l'
56+
57+
table.add_row(['name', utils.lookup(_firewall, 'networkGateway', 'name')])
58+
table.add_row(['datacenter', utils.lookup(_firewall, 'datacenter', 'longName')])
59+
table.add_row(['public ip', utils.lookup(_firewall, 'networkGateway', 'publicIpAddress', 'ipAddress')])
60+
table.add_row(['private ip', utils.lookup(_firewall, 'networkGateway', 'privateIpAddress', 'ipAddress')])
61+
table.add_row(['public ipv6', utils.lookup(_firewall, 'networkGateway', 'publicIpv6Address', 'ipAddress')])
62+
table.add_row(['public vlan', utils.lookup(_firewall, 'networkGateway', 'publicVlan', 'vlanNumber')])
63+
table.add_row(['private vlan', utils.lookup(_firewall, 'networkGateway', 'privateVlan', 'vlanNumber')])
64+
table.add_row(['type', _firewall.get('firewallType')])
65+
66+
if credentials:
67+
table.add_row(['fortiGate username', utils.lookup(_firewall, 'managementCredentials', 'username')])
68+
table.add_row(['fortiGate password', utils.lookup(_firewall, 'managementCredentials', 'password')])
69+
70+
rules = mgr.get_dedicated_fwl_rules(firewall_id)
71+
if len(rules) != 0:
72+
table.add_row(['rules', get_rules_table(rules)])
73+
else:
74+
table.add_row(['rules', '-'])
75+
76+
if firewall_type == 'vs' or firewall_type == 'server':
77+
rules = mgr.get_standard_fwl_rules(firewall_id)
78+
table = get_rules_table(rules)
2779

28-
table.add_row(['id', _firewall.get('id')])
29-
table.add_row(['primaryIpAddress', _firewall.get('primaryIpAddress')])
30-
table.add_row(['datacenter', utils.lookup(_firewall, 'datacenter', 'longName')])
31-
table.add_row(['networkVlan', utils.lookup(_firewall, 'networkVlan', 'name')])
32-
table.add_row(['networkVlaniD', utils.lookup(_firewall, 'networkVlan', 'id')])
80+
env.fout(table)
3381

34-
if firewall_type == 'vlan':
35-
rules = mgr.get_dedicated_fwl_rules(firewall_id)
3682
else:
37-
rules = mgr.get_standard_fwl_rules(firewall_id)
38-
table.add_row(['rules', get_rules_table(rules)])
39-
env.fout(table)
83+
click.secho('Invalid firewall type %s: firewall type should be either vlan, multiVlan, vs or server.'
84+
% firewall_type, fg='red')
85+
return
4086

4187

4288
def get_rules_table(rules):

SoftLayer/CLI/firewall/list.py

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ def cli(env):
1818
table = formatting.Table(['firewall id',
1919
'type',
2020
'features',
21-
'server/vlan id'])
21+
'server/vlan id'], title='Single Server Firewalls')
2222
fwvlans = mgr.get_firewalls()
2323
dedicated_firewalls = [firewall for firewall in fwvlans
2424
if firewall['dedicatedFirewallFlag']]
@@ -70,7 +70,27 @@ def cli(env):
7070
'hardwareId')
7171
])
7272

73+
table_gatewalls = formatting.Table(['Id',
74+
'firewall',
75+
'type',
76+
'Hostname',
77+
'Location',
78+
'Public Ip',
79+
'Private Ip',
80+
'Associated vlan',
81+
'status'], title='Multi Vlan Firewall')
82+
fw_gatewwalls = mgr.get_firewalls_gatewalls()
83+
84+
for gatewalls in fw_gatewwalls:
85+
table_gatewalls.add_row([gatewalls['networkFirewall']['id'], gatewalls.get('name'),
86+
gatewalls['networkFirewall']['firewallType'],
87+
gatewalls['members'][0]['hardware']['hostname'],
88+
gatewalls['networkFirewall']['datacenter']['name'],
89+
gatewalls['publicIpAddress']['ipAddress'],
90+
gatewalls['privateIpAddress']['ipAddress'],
91+
len(gatewalls['insideVlans']), gatewalls['status']['keyName']])
7392
env.fout(table)
93+
env.fout(table_gatewalls)
7494

7595

7696
def has_firewall_component(server):

SoftLayer/fixtures/SoftLayer_Account.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,3 +1228,41 @@
12281228
'projectedPublicBandwidthUsage': 9.88,
12291229
'totalBandwidthAllocated': 3361
12301230
}]
1231+
1232+
getNetworkGateways = [{
1233+
'id': 615448,
1234+
'name': 'testFirewall-cgallo',
1235+
'networkSpace': 'BOTH',
1236+
'insideVlans': [],
1237+
'members': [
1238+
{
1239+
'id': 687820,
1240+
'hardware': {
1241+
'hostname': 'dft03.pod03.dal13'
1242+
}
1243+
}
1244+
],
1245+
'networkFirewall': {
1246+
'id': 17438,
1247+
'datacenter': {
1248+
'name': 'dal13'
1249+
},
1250+
'firewallType': 'fortigate-security-appliance-10gb',
1251+
'rules': []
1252+
},
1253+
'privateIpAddress': {
1254+
'ipAddress': '10.37.115.70'
1255+
},
1256+
'publicIpAddress': {
1257+
'ipAddress': '67.228.206.245'
1258+
},
1259+
'publicVlan': {
1260+
'id': 3228726,
1261+
'primaryRouter': {
1262+
'hostname': 'fcr03a.dal13'
1263+
}
1264+
},
1265+
'status': {
1266+
'keyName': 'ACTIVE'
1267+
}
1268+
}]

SoftLayer/fixtures/SoftLayer_Network_Vlan_Firewall.py

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,133 @@
4949
}
5050
]
5151
},
52+
"firewallType": "fortigate-security-appliance-10gb",
53+
"managementCredentials": {
54+
"createDate": "2022-05-17T13:59:17-06:00",
55+
"id": 74604882,
56+
"modifyDate": "2022-05-17T13:59:17-06:00",
57+
"password": "test1234",
58+
"port": 23,
59+
"softwareId": 67804284,
60+
"username": "myusername"
61+
},
62+
"networkGateway": {
63+
"accountId": 307608,
64+
"groupNumber": 1,
65+
"id": 615448,
66+
"name": "testFirewall",
67+
"networkSpace": "BOTH",
68+
"privateIpAddressId": 188996652,
69+
"privateVlanId": 3228724,
70+
"publicIpAddressId": 188996794,
71+
"publicIpv6AddressId": 188996808,
72+
"publicVlanId": 3228726,
73+
"statusId": 1,
74+
"insideVlans": [],
75+
"members": [
76+
{
77+
"hardwareId": 3222842,
78+
"id": 687820,
79+
"networkGatewayId": 615448,
80+
"priority": 254,
81+
"networkGateway": None
82+
}
83+
],
84+
"privateIpAddress": {
85+
"id": 188996652,
86+
"ipAddress": "10.37.115.70",
87+
"isBroadcast": False,
88+
"isGateway": False,
89+
"isNetwork": False,
90+
"isReserved": True,
91+
"subnetId": 2552734,
92+
"subnet": {
93+
"broadcastAddress": "10.37.115.127",
94+
"cidr": 26,
95+
"gateway": "10.37.115.65",
96+
"id": 2552734,
97+
"isCustomerOwned": False,
98+
"isCustomerRoutable": False,
99+
"modifyDate": "2022-05-17T13:59:16-06:00",
100+
"netmask": "255.255.255.192",
101+
"networkIdentifier": "10.37.115.64",
102+
"networkVlanId": 3228724,
103+
"sortOrder": "1",
104+
"subnetType": "ADDITIONAL_PRIMARY",
105+
"totalIpAddresses": "64",
106+
"usableIpAddressCount": "61",
107+
"version": 4
108+
}
109+
},
110+
"privateVlan": {
111+
"accountId": 307608,
112+
"fullyQualifiedName": "dal13.bcr03.1330",
113+
"id": 3228724,
114+
"modifyDate": "2022-05-17T14:01:14-06:00",
115+
"primarySubnetId": 2625456,
116+
"vlanNumber": 1330
117+
},
118+
"publicIpAddress": {
119+
"id": 188996794,
120+
"ipAddress": "67.228.206.245",
121+
"isBroadcast": False,
122+
"isGateway": False,
123+
"isNetwork": False,
124+
"isReserved": True,
125+
"subnetId": 66444,
126+
"subnet": {
127+
"broadcastAddress": "67.228.206.247",
128+
"cidr": 29,
129+
"gateway": "67.228.206.241",
130+
"id": 66444,
131+
"isCustomerOwned": False,
132+
"isCustomerRoutable": False,
133+
"modifyDate": "2022-05-17T13:59:16-06:00",
134+
"netmask": "255.255.255.248",
135+
"networkIdentifier": "67.228.206.240",
136+
"networkVlanId": 3228726,
137+
"sortOrder": "1",
138+
"subnetType": "ADDITIONAL_PRIMARY",
139+
"totalIpAddresses": "8",
140+
"usableIpAddressCount": "5",
141+
"version": 4
142+
}
143+
},
144+
"publicIpv6Address": {
145+
"id": 188996808,
146+
"ipAddress": "2607:f0d0:2703:0039:0000:0000:0000:0004",
147+
"isBroadcast": False,
148+
"isGateway": False,
149+
"isNetwork": False,
150+
"isReserved": True,
151+
"subnetId": 2547678,
152+
"subnet": {
153+
"broadcastAddress": "",
154+
"cidr": 64,
155+
"gateway": "2607:f0d0:2703:0039:0000:0000:0000:0001",
156+
"id": 2547678,
157+
"isCustomerOwned": False,
158+
"isCustomerRoutable": False,
159+
"modifyDate": "2022-05-17T13:59:16-06:00",
160+
"netmask": "ffff:ffff:ffff:ffff:0000:0000:0000:0000",
161+
"networkIdentifier": "2607:f0d0:2703:0039:0000:0000:0000:0000",
162+
"networkVlanId": 3228726,
163+
"sortOrder": "4",
164+
"subnetType": "PRIMARY_6",
165+
"totalIpAddresses": "18446744073709551616",
166+
"usableIpAddressCount": "18446744073709551614",
167+
"version": 6
168+
}
169+
},
170+
"publicVlan": {
171+
"accountId": 307608,
172+
"fullyQualifiedName": "dal13.fcr03.1255",
173+
"id": 3228726,
174+
"modifyDate": "2022-05-17T14:00:42-06:00",
175+
"primarySubnetId": 2623338,
176+
"vlanNumber": 1255
177+
}
178+
},
52179
"rules": [
53180
{'destinationIpAddress': 'any on server',
54181
'protocol': 'tcp',

SoftLayer/managers/firewall.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,8 +297,25 @@ def get_instance(self, firewall_id, mask=None):
297297
:param integer firewall_id: the instance ID of the standard firewall
298298
"""
299299
if not mask:
300-
mask = 'mask[datacenter,networkVlan]'
300+
mask = 'mask[firewallType,networkGateway[insideVlans,members,privateIpAddress,publicIpAddress,' \
301+
'publicIpv6Address,privateVlan,publicVlan],datacenter,managementCredentials,networkVlan]'
301302

302303
svc = self.client['Network_Vlan_Firewall']
303304

304305
return svc.getObject(id=firewall_id, mask=mask)
306+
307+
def get_firewalls_gatewalls(self):
308+
"""Returns a list of all gateway firewalls (gatewalls) on the account.
309+
310+
returns: A list of gateway firewalls (gatewalls) on the current account.
311+
"""
312+
mask = 'mask[id,networkSpace,name,' \
313+
'networkFirewall[id,firewallType,datacenter[name]],' \
314+
'status[keyName],' \
315+
'insideVlans[id],' \
316+
'privateIpAddress[ipAddress],' \
317+
'publicVlan[id,primaryRouter[hostname]],' \
318+
'publicIpAddress[ipAddress],members[id,hardware[hostname]]]'
319+
_filter = {"networkGateways": {"networkFirewall": {"operation": "not null"}}}
320+
321+
return self.account.getNetworkGateways(mask=mask, filter=_filter)

0 commit comments

Comments
 (0)