softlayer_api 3.0.b1 → 3.0.b2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.textile +7 -2
- data/examples/order_bare_metal_package.rb +2 -2
- data/examples/order_server_firewall.rb +63 -0
- data/lib/softlayer/APIParameterFilter.rb +8 -1
- data/lib/softlayer/Account.rb +20 -2
- data/lib/softlayer/BareMetalServer.rb +39 -8
- data/lib/softlayer/BareMetalServerOrder.rb +12 -12
- data/lib/softlayer/BareMetalServerOrder_Package.rb +5 -5
- data/lib/softlayer/Client.rb +4 -2
- data/lib/softlayer/Config.rb +3 -3
- data/lib/softlayer/ImageTemplate.rb +11 -11
- data/lib/softlayer/ModelBase.rb +1 -1
- data/lib/softlayer/NetworkComponent.rb +14 -0
- data/lib/softlayer/ProductItemCategory.rb +17 -13
- data/lib/softlayer/ProductPackage.rb +60 -10
- data/lib/softlayer/Server.rb +30 -9
- data/lib/softlayer/ServerFirewall.rb +263 -0
- data/lib/softlayer/ServerFirewallOrder.rb +84 -0
- data/lib/softlayer/Service.rb +17 -13
- data/lib/softlayer/Ticket.rb +8 -8
- data/lib/softlayer/VLANFirewall.rb +280 -0
- data/lib/softlayer/VLANFirewallOrder.rb +93 -0
- data/lib/softlayer/VirtualServer.rb +8 -5
- data/lib/softlayer/VirtualServerOrder.rb +16 -16
- data/lib/softlayer/VirtualServerUpgradeOrder.rb +21 -21
- data/lib/softlayer/base.rb +1 -1
- data/lib/softlayer_api.rb +5 -0
- metadata +8 -2
@@ -0,0 +1,84 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
|
3
|
+
#
|
4
|
+
# For licensing information see the LICENSE.md file in the project root.
|
5
|
+
#++
|
6
|
+
|
7
|
+
module SoftLayer
|
8
|
+
#
|
9
|
+
# This class allows you to order a Firewall for a server
|
10
|
+
#
|
11
|
+
class ServerFirewallOrder
|
12
|
+
# The server that you are ordering the firewall for.
|
13
|
+
attr_reader :server
|
14
|
+
|
15
|
+
##
|
16
|
+
# Create a new order for the given server
|
17
|
+
def initialize (server)
|
18
|
+
@server = server
|
19
|
+
|
20
|
+
raise ArgumentError, "Server does not have an active Public interface" if server.firewall_port_speed == 0
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# Calls the SoftLayer API to verify that the template provided by this order is valid
|
25
|
+
# This routine will return the order template generated by the API or will throw an exception
|
26
|
+
#
|
27
|
+
# This routine will not actually create a Bare Metal Instance and will not affect billing.
|
28
|
+
#
|
29
|
+
# If you provide a block, it will receive the order template as a parameter and
|
30
|
+
# the block may make changes to the template before it is submitted.
|
31
|
+
def verify()
|
32
|
+
order_template = firewall_order_template
|
33
|
+
order_template = yield order_template if block_given?
|
34
|
+
|
35
|
+
server.softlayer_client[:Product_Order].verifyOrder(order_template)
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Calls the SoftLayer API to place an order for a new server based on the template in this
|
40
|
+
# order. If this succeeds then you will be billed for the new server.
|
41
|
+
#
|
42
|
+
# If you provide a block, it will receive the order template as a parameter and
|
43
|
+
# the block may make changes to the template before it is submitted.
|
44
|
+
def place_order!()
|
45
|
+
order_template = firewall_order_template
|
46
|
+
order_template = yield order_template if block_given?
|
47
|
+
|
48
|
+
server.softlayer_client[:Product_Order].placeOrder(order_template)
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
##
|
54
|
+
# Returns a hash of the creation options formatted to be sent *to*
|
55
|
+
# the SoftLayer API for either verification or completion
|
56
|
+
def firewall_order_template
|
57
|
+
client = server.softlayer_client
|
58
|
+
additional_products_package = SoftLayer::ProductPackage.additional_products_package(client)
|
59
|
+
|
60
|
+
template = {
|
61
|
+
'complexType' => 'SoftLayer_Container_Product_Order_Network_Protection_Firewall',
|
62
|
+
'quantity' => 1,
|
63
|
+
'packageId' => additional_products_package.id
|
64
|
+
}
|
65
|
+
|
66
|
+
if @server.service.service_name == "SoftLayer_Virtual_Guest"
|
67
|
+
template['virtualGuests'] = [{'id' => @server.id}]
|
68
|
+
else
|
69
|
+
template['hardware'] = [{'id' => @server.id}]
|
70
|
+
end
|
71
|
+
|
72
|
+
expected_description = "#{@server.firewall_port_speed}Mbps Hardware Firewall"
|
73
|
+
firewall_items = additional_products_package.items_with_description(expected_description)
|
74
|
+
|
75
|
+
raise "Could not find a price item matching the description '#{expected_description}'" if firewall_items.empty?
|
76
|
+
|
77
|
+
firewall_item = firewall_items[0]
|
78
|
+
|
79
|
+
template['prices'] = [{ 'id' => firewall_item.price_id }] if firewall_item.respond_to?(:price_id)
|
80
|
+
|
81
|
+
template
|
82
|
+
end
|
83
|
+
end # class ServerFirewallOrder
|
84
|
+
end # module SoftLayer
|
data/lib/softlayer/Service.rb
CHANGED
@@ -20,6 +20,19 @@
|
|
20
20
|
|
21
21
|
require 'xmlrpc/client'
|
22
22
|
|
23
|
+
# utility routine for swapping constants without warnings.
|
24
|
+
def with_warnings(flag)
|
25
|
+
old_verbose, $VERBOSE = $VERBOSE, flag
|
26
|
+
yield
|
27
|
+
ensure
|
28
|
+
$VERBOSE = old_verbose
|
29
|
+
end
|
30
|
+
|
31
|
+
# enable parsing of "nil" values in structures returned from the API
|
32
|
+
with_warnings(nil) {
|
33
|
+
XMLRPC::Config.const_set('ENABLE_NIL_PARSER', true)
|
34
|
+
}
|
35
|
+
|
23
36
|
# The XML-RPC spec calls for the "faultCode" in faults to be an integer
|
24
37
|
# but the SoftLayer XML-RPC API can return strings as the "faultCode"
|
25
38
|
#
|
@@ -30,25 +43,15 @@ module XMLRPC::Convert
|
|
30
43
|
def self.fault(hash)
|
31
44
|
if hash.kind_of? Hash and hash.size == 2 and
|
32
45
|
hash.has_key? "faultCode" and hash.has_key? "faultString" and
|
33
|
-
(hash[
|
46
|
+
(hash['faultCode'].kind_of?(Integer) || hash['faultCode'].kind_of?(String)) and hash['faultString'].kind_of? String
|
34
47
|
|
35
|
-
XMLRPC::FaultException.new(hash[
|
48
|
+
XMLRPC::FaultException.new(hash['faultCode'], hash['faultString'])
|
36
49
|
else
|
37
50
|
super
|
38
51
|
end
|
39
52
|
end
|
40
53
|
end
|
41
54
|
|
42
|
-
# The XMLRPC client uses a fixed user agent string, but we want to
|
43
|
-
# supply our own, so we add a method to XMLRPC::Client that lets
|
44
|
-
# us change it.
|
45
|
-
class XMLRPC::Client
|
46
|
-
def self.set_user_agent(new_agent)
|
47
|
-
remove_const(:USER_AGENT) if const_defined?(:USER_AGENT)
|
48
|
-
const_set(:USER_AGENT, new_agent)
|
49
|
-
end
|
50
|
-
end
|
51
|
-
|
52
55
|
module SoftLayer
|
53
56
|
# = SoftLayer API Service
|
54
57
|
#
|
@@ -62,7 +65,7 @@ module SoftLayer
|
|
62
65
|
#
|
63
66
|
# client = SoftLayer::Client.new(:username => "Joe", :api_key=>"feeddeadbeefbadfood...")
|
64
67
|
# account_service = client.service_named("Account") # returns the SoftLayer_Account service
|
65
|
-
# account_service = client[
|
68
|
+
# account_service = client[:Account] # Exactly the same as above
|
66
69
|
#
|
67
70
|
# For backward compatibility, a service can be constructed by passing
|
68
71
|
# client initialization options, however if you do so you will need to
|
@@ -315,6 +318,7 @@ using either client.service_named('<service_name_here>') or client['<service_nam
|
|
315
318
|
end
|
316
319
|
|
317
320
|
@xmlrpc_client.http.set_debug_output($stderr)
|
321
|
+
@xmlrpc_client.http.instance_variable_set(:@verify_mode, OpenSSL::SSL::VERIFY_NONE)
|
318
322
|
end # $DEBUG
|
319
323
|
end
|
320
324
|
|
data/lib/softlayer/Ticket.rb
CHANGED
@@ -25,14 +25,14 @@ module SoftLayer
|
|
25
25
|
##
|
26
26
|
# Returns true if the ticket has "unread" updates
|
27
27
|
def has_updates?
|
28
|
-
self[
|
28
|
+
self['newUpdatesFlag']
|
29
29
|
end
|
30
30
|
|
31
31
|
##
|
32
32
|
# Returns true if the ticket is a server admin ticket
|
33
33
|
def server_admin_ticket?
|
34
34
|
# note that serverAdministrationFlag comes from the server as an Integer (0, or 1)
|
35
|
-
self[
|
35
|
+
self['serverAdministrationFlag'] != 0
|
36
36
|
end
|
37
37
|
|
38
38
|
##
|
@@ -46,7 +46,7 @@ module SoftLayer
|
|
46
46
|
# Override of service from ModelBase. Returns the SoftLayer_Ticket service
|
47
47
|
# set up to talk to the ticket with my ID.
|
48
48
|
def service
|
49
|
-
return softlayer_client[
|
49
|
+
return softlayer_client[:Ticket].object_with_id(self.id)
|
50
50
|
end
|
51
51
|
|
52
52
|
##
|
@@ -96,7 +96,7 @@ module SoftLayer
|
|
96
96
|
softlayer_client = client || Client.default_client
|
97
97
|
raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
|
98
98
|
|
99
|
-
@ticket_subjects = softlayer_client[
|
99
|
+
@ticket_subjects = softlayer_client[:Ticket_Subject].getAllObjects();
|
100
100
|
end
|
101
101
|
|
102
102
|
@ticket_subjects
|
@@ -122,7 +122,7 @@ module SoftLayer
|
|
122
122
|
object_mask = default_object_mask.to_sl_object_mask
|
123
123
|
end
|
124
124
|
|
125
|
-
ticket_data = softlayer_client[
|
125
|
+
ticket_data = softlayer_client[:Ticket].object_with_id(ticket_id).object_mask(object_mask).getObject()
|
126
126
|
|
127
127
|
return new(softlayer_client, ticket_data)
|
128
128
|
end
|
@@ -153,8 +153,8 @@ module SoftLayer
|
|
153
153
|
assigned_user_id = options[:assigned_user_id]
|
154
154
|
|
155
155
|
if(nil == assigned_user_id)
|
156
|
-
current_user = softlayer_client[
|
157
|
-
assigned_user_id = current_user[
|
156
|
+
current_user = softlayer_client[:Account].object_mask("id").getCurrentUser()
|
157
|
+
assigned_user_id = current_user['id']
|
158
158
|
end
|
159
159
|
|
160
160
|
new_ticket = {
|
@@ -164,7 +164,7 @@ module SoftLayer
|
|
164
164
|
'title' => title
|
165
165
|
}
|
166
166
|
|
167
|
-
ticket_data = softlayer_client[
|
167
|
+
ticket_data = softlayer_client[:Ticket].createStandardTicket(new_ticket, body)
|
168
168
|
return new(softlayer_client, ticket_data)
|
169
169
|
end
|
170
170
|
end
|
@@ -0,0 +1,280 @@
|
|
1
|
+
#--
|
2
|
+
# Copyright (c) 2014 SoftLayer Technologies, Inc. All rights reserved.
|
3
|
+
#
|
4
|
+
# For licensing information see the LICENSE.md file in the project root.
|
5
|
+
#++
|
6
|
+
|
7
|
+
module SoftLayer
|
8
|
+
# The VLANFirewall class represents the firewall that protects
|
9
|
+
# all the servers on a VLAN in the SoftLayer Environment. It is
|
10
|
+
# also known as a "Dedicated Firewall" in some documentation.
|
11
|
+
#
|
12
|
+
# Instances of this class are a bit odd because they actually represent a
|
13
|
+
# VLAN (the VLAN protected by the firewall to be specific), and not the
|
14
|
+
# physical hardware implementing the firewall itself. (although the device
|
15
|
+
# is accessible as the "networkVlanFirewall" property)
|
16
|
+
#
|
17
|
+
# As a result, instances of this class correspond to certain instances
|
18
|
+
# in the SoftLayer_Network_Vlan service.
|
19
|
+
#
|
20
|
+
class VLANFirewall < SoftLayer::ModelBase
|
21
|
+
include ::SoftLayer::DynamicAttribute
|
22
|
+
|
23
|
+
##
|
24
|
+
#:attr_reader:
|
25
|
+
#
|
26
|
+
# The number of the VLAN protected by this firewall.
|
27
|
+
#
|
28
|
+
sl_attr :VLAN_number, 'vlanNumber'
|
29
|
+
|
30
|
+
##
|
31
|
+
# :attr_reader:
|
32
|
+
#
|
33
|
+
# The set of rules applied by this firewall to incoming traffic.
|
34
|
+
# The object will retrieve the rules from the network API every
|
35
|
+
# time you ask it for the rules.
|
36
|
+
#
|
37
|
+
# The code will sort the rules by their "orderValue" which is the
|
38
|
+
# order that the firewall applies the rules, however please see
|
39
|
+
# the important note in change_rules! concerning the "orderValue"
|
40
|
+
# property of the rules.
|
41
|
+
sl_dynamic_attr :rules do |firewall_rules|
|
42
|
+
firewall_rules.should_update? do
|
43
|
+
# firewall rules update every time you ask for them.
|
44
|
+
return true
|
45
|
+
end
|
46
|
+
|
47
|
+
firewall_rules.to_update do
|
48
|
+
acl_id = rules_ACL_id()
|
49
|
+
rules_data = self.softlayer_client[:Network_Firewall_AccessControlList].object_with_id(acl_id).object_mask(self.class.default_rules_mask).getRules
|
50
|
+
rules_data.sort { |lhs, rhs| lhs['orderValue'] <=> rhs['orderValue'] }
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
##
|
55
|
+
# Returns the name of the primary router the firewall is attached to.
|
56
|
+
# This is often a "customer router" in one of the datacenters.
|
57
|
+
def primaryRouter
|
58
|
+
return self['primaryRouter']['hostname']
|
59
|
+
end
|
60
|
+
|
61
|
+
##
|
62
|
+
# The fully qualified domain name of the physical device the
|
63
|
+
# firewall is implemented by.
|
64
|
+
def fullyQualifiedDomainName
|
65
|
+
if self.has_sl_property?('networkVlanFirewall')
|
66
|
+
return self['networkVlanFirewall']['fullyQualifiedDomainName']
|
67
|
+
else
|
68
|
+
return @softlayer_hash
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
##
|
73
|
+
# Returns true if this is a "high availability" firewall, that is a firewall
|
74
|
+
# that exists as one member of a redundant pair.
|
75
|
+
def high_availability?
|
76
|
+
# note that highAvailabilityFirewallFlag is a boolean in the softlayer hash
|
77
|
+
return self.has_sl_property?('highAvailabilityFirewallFlag') && self['highAvailabilityFirewallFlag']
|
78
|
+
end
|
79
|
+
|
80
|
+
##
|
81
|
+
# Cancel the firewall
|
82
|
+
#
|
83
|
+
# This method cancels the firewall and releases its
|
84
|
+
# resources. The cancellation is processed immediately!
|
85
|
+
# Call this method with careful deliberation!
|
86
|
+
#
|
87
|
+
# Notes is a string that describes the reason for the
|
88
|
+
# cancellation. If empty or nil, a default string will
|
89
|
+
# be added.
|
90
|
+
#
|
91
|
+
def cancel!(notes = nil)
|
92
|
+
user = self.softlayer_client[:Account].object_mask("mask[id,account.id]").getCurrentUser
|
93
|
+
notes = "Cancelled by a call to #{__method__} in the softlayer_api gem" if notes == nil || notes == ""
|
94
|
+
|
95
|
+
cancellation_request = {
|
96
|
+
'accountId' => user['account']['id'],
|
97
|
+
'userId' => user['id'],
|
98
|
+
'items' => [ {
|
99
|
+
'billingItemId' => self['networkVlanFirewall']['billingItem']['id'],
|
100
|
+
'immediateCancellationFlag' => true
|
101
|
+
} ],
|
102
|
+
'notes' => notes
|
103
|
+
}
|
104
|
+
|
105
|
+
self.softlayer_client[:Billing_Item_Cancellation_Request].createObject(cancellation_request)
|
106
|
+
end
|
107
|
+
|
108
|
+
##
|
109
|
+
# Change the set of rules for the firewall.
|
110
|
+
# The rules_data parameter should be an array of hashes where
|
111
|
+
# each hash gives the conditions of the rule. The keys of the
|
112
|
+
# hashes should be entries from the array returned by
|
113
|
+
# SoftLayer::ServerFirewall.default_rules_mask_keys
|
114
|
+
#
|
115
|
+
# *NOTE!* When changing the rules on the firewall, you must
|
116
|
+
# pass in a complete set of rules each time. The rules you
|
117
|
+
# submit will replace the entire ruleset on the destination
|
118
|
+
# firewall.
|
119
|
+
#
|
120
|
+
# *NOTE!* The rules themselves have an "orderValue" property.
|
121
|
+
# It is this property, and *not* the order that the rules are
|
122
|
+
# found in the rules_data array, which will determine in which
|
123
|
+
# order the firewall applies its rules to incomming traffic.
|
124
|
+
#
|
125
|
+
# *NOTE!* Changes to the rules are not applied immediately
|
126
|
+
# on the server side. Instead, they are enqueued by the
|
127
|
+
# firewall update service and updated periodically. A typical
|
128
|
+
# update will take about one minute to apply, but times may vary
|
129
|
+
# depending on the system load and other circumstances.
|
130
|
+
def change_rules!(rules_data)
|
131
|
+
change_object = {
|
132
|
+
"firewallContextAccessControlListId" => rules_ACL_id(),
|
133
|
+
"rules" => rules_data
|
134
|
+
}
|
135
|
+
|
136
|
+
self.softlayer_client[:Network_Firewall_Update_Request].createObject(change_object)
|
137
|
+
end
|
138
|
+
|
139
|
+
##
|
140
|
+
# This method asks the firewall to ignore its rule set and pass all traffic
|
141
|
+
# through the firewall. Compare the behavior of this routine with
|
142
|
+
# change_routing_bypass!
|
143
|
+
#
|
144
|
+
# It is important to note that changing the bypass to :bypass_firewall_rules
|
145
|
+
# removes ALL the protection offered by the firewall. This routine should be
|
146
|
+
# used with extreme discretion.
|
147
|
+
#
|
148
|
+
# Note that this routine queues a rule change and rule changes may take
|
149
|
+
# time to process. The change will probably not take effect immediately.
|
150
|
+
#
|
151
|
+
# The two symbols accepted as arguments by this routine are:
|
152
|
+
# :apply_firewall_rules - The rules of the firewall are applied to traffic. This is the default operating mode of the firewall
|
153
|
+
# :bypass_firewall_rules - The rules of the firewall are ignored. In this configuration the firewall provides no protection.
|
154
|
+
#
|
155
|
+
def change_rules_bypass!(bypass_symbol)
|
156
|
+
change_object = {
|
157
|
+
"firewallContextAccessControlListId" => rules_ACL_id(),
|
158
|
+
"rules" => self.rules
|
159
|
+
}
|
160
|
+
|
161
|
+
case bypass_symbol
|
162
|
+
when :apply_firewall_rules
|
163
|
+
change_object['bypassFlag'] = false
|
164
|
+
self.softlayer_client[:Network_Firewall_Update_Request].createObject(change_object)
|
165
|
+
when :bypass_firewall_rules
|
166
|
+
change_object['bypassFlag'] = true
|
167
|
+
self.softlayer_client[:Network_Firewall_Update_Request].createObject(change_object)
|
168
|
+
else
|
169
|
+
raise ArgumentError, "An invalid parameter was sent to #{__method__}. It accepts :apply_firewall_rules and :bypass_firewall_rules"
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
##
|
174
|
+
# This method allows you to route traffic around the firewall
|
175
|
+
# and directly to the servers it protects. Compare the behavior of this routine with
|
176
|
+
# change_rules_bypass!
|
177
|
+
#
|
178
|
+
# It is important to note that changing the routing to :route_around_firewall
|
179
|
+
# removes ALL the protection offered by the firewall. This routine should be
|
180
|
+
# used with extreme discretion.
|
181
|
+
#
|
182
|
+
# Note that this routine constructs a transaction. The Routing change
|
183
|
+
# may not happen immediately.
|
184
|
+
#
|
185
|
+
# The two symbols accepted as arguments by the routine are:
|
186
|
+
# :route_through_firewall - Network traffic is sent through the firewall to the servers in the VLAN segment it protects. This is the usual operating mode of the firewall.
|
187
|
+
# :route_around_firewall - Network traffic will be sent directly to the servers in the VLAN segment protected by this firewall. This means that the firewall will *NOT* be protecting those servers.
|
188
|
+
#
|
189
|
+
def change_routing_bypass!(routing_symbol)
|
190
|
+
vlan_firewall_id = self['networkVlanFirewall']['id']
|
191
|
+
|
192
|
+
raise "Could not identify the device for a VLAN firewall" if !vlan_firewall_id
|
193
|
+
|
194
|
+
case routing_symbol
|
195
|
+
when :route_through_firewall
|
196
|
+
self.softlayer_client[:Network_Vlan_Firewall].object_with_id(vlan_firewall_id).updateRouteBypass(false)
|
197
|
+
when :route_around_firewall
|
198
|
+
self.softlayer_client[:Network_Vlan_Firewall].object_with_id(vlan_firewall_id).updateRouteBypass(true)
|
199
|
+
else
|
200
|
+
raise ArgumentError, "An invalid parameter was sent to #{__method__}. It accepts :route_through_firewall and :route_around_firewall"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
##
|
205
|
+
# Collect a list of the firewalls on the account.
|
206
|
+
#
|
207
|
+
# This list is obtained by asking the account for all the VLANs
|
208
|
+
# it has that also have a networkVlanFirewall component.
|
209
|
+
def self.find_firewalls(client = nil)
|
210
|
+
softlayer_client = client || Client.default_client
|
211
|
+
raise "#{__method__} requires a client but none was given and Client::default_client is not set" if !softlayer_client
|
212
|
+
|
213
|
+
# only VLAN firewallas have a networkVlanFirewall component
|
214
|
+
vlan_firewall_filter = SoftLayer::ObjectFilter.new() { |filter|
|
215
|
+
filter.accept("networkVlans.networkVlanFirewall").when_it is_not_null
|
216
|
+
}
|
217
|
+
|
218
|
+
vlan_firewalls = softlayer_client[:Account].object_mask(vlan_firewall_mask).object_filter(vlan_firewall_filter).getNetworkVlans
|
219
|
+
vlan_firewalls.collect { |firewall_data| SoftLayer::VLANFirewall.new(softlayer_client, firewall_data)}
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
#--
|
224
|
+
# Methods for the SoftLayer model
|
225
|
+
#++
|
226
|
+
|
227
|
+
def service
|
228
|
+
# Objects of this class are a bit odd because they actually represent VLANs (the VLAN protected by the firewall)
|
229
|
+
# and not the physical hardware implementing the firewall itself. (although the device is accessible as the
|
230
|
+
# "networkVlanFirewall" property)
|
231
|
+
self.softlayer_client[:Network_Vlan].object_with_id(self.id)
|
232
|
+
end
|
233
|
+
|
234
|
+
def softlayer_properties(object_mask = nil)
|
235
|
+
service = self.service
|
236
|
+
service = service.object_mask(object_mask) if object_mask
|
237
|
+
service.object_mask(self.class.vlan_firewall_mask).getObject
|
238
|
+
end
|
239
|
+
|
240
|
+
#--
|
241
|
+
#++
|
242
|
+
private
|
243
|
+
|
244
|
+
# Searches the set of access control lists for the firewall device in order to locate the one that
|
245
|
+
# sits on the "outside" side of the network and handles 'in'coming traffic.
|
246
|
+
def rules_ACL_id
|
247
|
+
outside_interface_data = self['firewallInterfaces'].find { |interface_data| interface_data['name'] == 'outside' }
|
248
|
+
incoming_ACL = outside_interface_data['firewallContextAccessControlLists'].find { |firewallACL_data| firewallACL_data['direction'] == 'in' } if outside_interface_data
|
249
|
+
|
250
|
+
if incoming_ACL
|
251
|
+
return incoming_ACL['id']
|
252
|
+
else
|
253
|
+
return nil
|
254
|
+
end
|
255
|
+
end
|
256
|
+
|
257
|
+
def self.vlan_firewall_mask
|
258
|
+
return "mask[primaryRouter,highAvailabilityFirewallFlag," +
|
259
|
+
"firewallInterfaces.firewallContextAccessControlLists," +
|
260
|
+
"networkVlanFirewall[id,datacenter,primaryIpAddress,firewallType,fullyQualifiedDomainName,billingItem.id]]"
|
261
|
+
end
|
262
|
+
|
263
|
+
def self.default_rules_mask
|
264
|
+
return { "mask" => default_rules_mask_keys }.to_sl_object_mask
|
265
|
+
end
|
266
|
+
|
267
|
+
def self.default_rules_mask_keys
|
268
|
+
['orderValue',
|
269
|
+
'action',
|
270
|
+
'destinationIpAddress',
|
271
|
+
'destinationIpSubnetMask',
|
272
|
+
'protocol',
|
273
|
+
'destinationPortRangeStart',
|
274
|
+
'destinationPortRangeEnd',
|
275
|
+
'sourceIpAddress',
|
276
|
+
'sourceIpSubnetMask',
|
277
|
+
'version']
|
278
|
+
end
|
279
|
+
end # class Firewall
|
280
|
+
end # module SoftLayer
|