esp_sdk 2.4.0 → 2.5.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eb2adf95c6d86093eac45d8f35aba16bfc4b92fd
4
- data.tar.gz: 866a1a8d25f13d6c948cf2c5763d32733c488706
3
+ metadata.gz: 985f05618a6621f6fd81b455b13b532c91712638
4
+ data.tar.gz: 773b7274d4889449a4264f8f19e869f4b9830798
5
5
  SHA512:
6
- metadata.gz: 8c956e5ead24371596d4b00c95d2d4a60d385a51c6ffc7fb1df4cfac3b3b73eff6ada2ee93bb36741eb54c12ee4a8c2f75d8c6d5e894b1f6b8291c063302d7e0
7
- data.tar.gz: b4bde23260e83f6819e757c86bb10b720a6378895885e2d806058ae9ea68e93519a1ca1d7ff6639d8265717378c3b864268610c5be78c7db877687386f2ee3e2
6
+ metadata.gz: 54b0c9606230136eff0b3c463467be3f9eebf1986b4e603622c1efa59e680496769b7d086ae13913be912df2c12e7ac2f1e5352e39a1ba18628ffc4c9e36828a
7
+ data.tar.gz: c398c98653b66c5adac110c958580662fb1bba451fa0d8db98cc6f435e6d1ed0f5f79c594a768bee60232d9b9799eeff230c65961ab1c4cc43e2917bb344667e
@@ -1,5 +1,10 @@
1
1
  ## Unreleased
2
2
 
3
+ ## 2.5.0 - 2016-07-20
4
+ ### Added
5
+ - Add custom signature definitions and results. Code for a custom signature is now created/updated under a definition. Running a definition for an on demand test creates a result record which will have errors and alerts when completed.
6
+ - This is a backwards incompatible change on the API. If you need to save or run code on a custom signature, make sure to use this version or later.
7
+
3
8
  ## 2.4.0 - 2016-06-30
4
9
  ### Added
5
10
  - Report relationship to ExternalAccount
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- esp_sdk (2.4.0)
4
+ esp_sdk (2.5.0)
5
5
  activeresource (~> 4.0.0)
6
6
  api-auth (~> 2.0.0)
7
7
  rack
data/lib/esp.rb CHANGED
@@ -102,11 +102,6 @@ module ESP
102
102
  autoload :Tag, File.expand_path(File.dirname(__FILE__) + '/esp/resources/tag')
103
103
  autoload :Region, File.expand_path(File.dirname(__FILE__) + '/esp/resources/region')
104
104
  autoload :Suppression, File.expand_path(File.dirname(__FILE__) + '/esp/resources/suppression')
105
- class Suppression
106
- autoload :UniqueIdentifier, File.expand_path(File.dirname(__FILE__) + '/esp/resources/suppression/unique_identifier')
107
- autoload :Signature, File.expand_path(File.dirname(__FILE__) + '/esp/resources/suppression/signature')
108
- autoload :Region, File.expand_path(File.dirname(__FILE__) + '/esp/resources/suppression/region')
109
- end
110
105
  autoload :Stat, File.expand_path(File.dirname(__FILE__) + '/esp/resources/stat')
111
106
  autoload :StatCustomSignature, File.expand_path(File.dirname(__FILE__) + '/esp/resources/stat_custom_signature')
112
107
  autoload :StatSignature, File.expand_path(File.dirname(__FILE__) + '/esp/resources/stat_signature')
@@ -114,9 +109,4 @@ module ESP
114
109
  autoload :StatService, File.expand_path(File.dirname(__FILE__) + '/esp/resources/stat_service')
115
110
  autoload :ExternalAccountCreator, File.expand_path(File.dirname(__FILE__) + '/../lib/esp/external_account_creator')
116
111
  autoload :AWSClients, File.expand_path(File.dirname(__FILE__) + '/../lib/esp/aws_clients')
117
- class Report
118
- module Export
119
- autoload :Integration, File.expand_path(File.dirname(__FILE__) + '/esp/resources/reports/export/integration')
120
- end
121
- end
122
112
  end
@@ -1,8 +1,12 @@
1
1
  module ESP
2
2
  class CustomSignature < ESP::Resource
3
+ autoload :Definition, File.expand_path(File.dirname(__FILE__) + '/custom_signature/definition')
4
+ autoload :Result, File.expand_path(File.dirname(__FILE__) + '/custom_signature/result')
5
+
3
6
  ##
4
7
  # The organization this custom signature belongs to.
5
8
  belongs_to :organization, class_name: 'ESP::Organization'
9
+ has_many :definitions, class_name: 'ESP::CustomSignature::Definition'
6
10
 
7
11
  ##
8
12
  # The collection of teams that belong to the custom_signature.
@@ -11,100 +15,6 @@ module ESP
11
15
  Team.where(custom_signatures_id_eq: id)
12
16
  end
13
17
 
14
- # Run a custom signature that has not been saved. Useful for debugging a custom signature.
15
- # Returns a collection of alerts.
16
- # Throws an error if not successful.
17
- #
18
- # ==== Parameters
19
- #
20
- # +arguments+ | Required | A hash of run arguments
21
- #
22
- # ===== Valid Arguments
23
- #
24
- # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-run-new] for valid arguments
25
- #
26
- # ==== Example
27
- # signature = "# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: 'count == 0')\r\n else\r\n pass(user_count: count, condition: 'count >= 1')\r\n end\r\nend\r\n"
28
- # alerts = ESP::CustomSignature.run!(external_account_id: 3, regions: ['us_east_1'], language: 'ruby', signature: signature)
29
- def self.run!(arguments = {})
30
- result = run(arguments)
31
- return result if result.is_a?(ActiveResource::Collection)
32
- result.message = result.errors.full_messages.join(' ')
33
- fail(ActiveResource::ResourceInvalid.new(result)) # rubocop:disable Style/RaiseArgs
34
- end
35
-
36
- # Run a custom signature that has not been saved. Useful for debugging a custom signature.
37
- # Returns a collection of alerts.
38
- # If not successful, returns a CustomSignature object with the errors object populated.
39
- #
40
- # ==== Parameters
41
- #
42
- # +arguments+ | Required | A hash of run arguments
43
- #
44
- # ===== Valid Arguments
45
- #
46
- # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-run-new] for valid arguments
47
- #
48
- # ==== Example
49
- # signature = "# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: 'count == 0')\r\n else\r\n pass(user_count: count, condition: 'count >= 1')\r\n end\r\nend\r\n"
50
- # alerts = ESP::CustomSignature.run(external_account_id: 3, regions: ['us_east_1'], language: 'ruby', signature: signature)
51
- def self.run(arguments = {})
52
- arguments = arguments.with_indifferent_access
53
- arguments[:regions] = Array(arguments[:regions])
54
- new(arguments).run
55
- end
56
-
57
- # Run this custom signature instance.
58
- # Returns a collection of alerts.
59
- # Throws an error if not successful.
60
- #
61
- # ==== Parameters
62
- #
63
- # +arguments+ | Required | A hash of run arguments
64
- #
65
- # ===== Valid Arguments
66
- #
67
- # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-run-existing] for valid arguments
68
- #
69
- # ==== Example
70
- # custom_signature = ESP::CustomSignature.find(365)
71
- # alerts = custom_signature.run!(external_account_id: 3, regions: ['us_east_1'])
72
- def run!(arguments = {})
73
- result = run(arguments)
74
- return result if result.is_a?(ActiveResource::Collection)
75
- self.message = errors.full_messages.join(' ')
76
- fail(ActiveResource::ResourceInvalid.new(self)) # rubocop:disable Style/RaiseArgs
77
- end
78
-
79
- # Run this custom signature instance.
80
- # Returns a collection of alerts.
81
- # If not successful, returns a CustomSignature object with the errors object populated.
82
- #
83
- # ==== Parameters
84
- #
85
- # +arguments+ | Required | A hash of run arguments
86
- #
87
- # ===== Valid Arguments
88
- #
89
- # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-run-existing] for valid arguments
90
- #
91
- # ==== Example
92
- # custom_signature = ESP::CustomSignature.find(365)
93
- # alerts = custom_signature.run(external_account_id: 3, regions: ['us_east_1'])
94
- def run(arguments = {})
95
- arguments = arguments.with_indifferent_access
96
-
97
- attributes['external_account_id'] ||= arguments[:external_account_id]
98
- attributes['regions'] ||= Array(arguments[:regions])
99
-
100
- response = connection.post endpoint, to_json
101
- ESP::Alert.send(:instantiate_collection, self.class.format.decode(response.body))
102
- rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::ResourceNotFound => error
103
- load_remote_errors(error, true)
104
- self.code = error.response.code
105
- self
106
- end
107
-
108
18
  # Create a suppression for this custom signature.
109
19
  #
110
20
  # ==== Parameter
@@ -175,8 +85,7 @@ module ESP
175
85
  #
176
86
  # ==== Example
177
87
  #
178
- # signature = "# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: 'count == 0')\r\n else\r\n pass(user_count: count, condition: 'count >= 1')\r\n end\r\nend\r\n"
179
- # custom_signature = ESP::CustomSignature.create(signature: signature, description: "A test custom signature.", identifier: "AWS::IAM::001", language: "ruby", name: "Test Signature", risk_level: "Medium")
88
+ # custom_signature = ESP::CustomSignature.create(description: "A test custom signature.", identifier: "AWS::IAM::001", name: "Test Signature", risk_level: "Medium")
180
89
 
181
90
  # :method: save
182
91
  # Create or update a CustomSignature
@@ -187,21 +96,10 @@ module ESP
187
96
  #
188
97
  # ==== Example
189
98
  #
190
- # signature = "# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: 'count == 0')\r\n else\r\n pass(user_count: count, condition: 'count >= 1')\r\n end\r\nend\r\n"
191
- # custom_signature = ESP::CustomSignature.new(signature: signature, description: "A test custom signature.", identifier: "AWS::IAM::001", language: "ruby", name: "Test Signature", risk_level: "Medium")
99
+ # custom_signature = ESP::CustomSignature.new(description: "A test custom signature.", identifier: "AWS::IAM::001", name: "Test Signature", risk_level: "Medium")
192
100
  # custom_signature.save
193
101
 
194
102
  # :method: destroy
195
103
  # Delete a CustomSignature
196
-
197
- private
198
-
199
- def endpoint
200
- if id.present?
201
- "#{self.class.prefix}custom_signatures/#{id}/run.json"
202
- else
203
- "#{self.class.prefix}custom_signatures/run.json"
204
- end
205
- end
206
104
  end
207
105
  end
@@ -0,0 +1,100 @@
1
+ module ESP
2
+ class CustomSignature
3
+ class Definition < ESP::Resource
4
+ self.prefix += "custom_signature_"
5
+
6
+ belongs_to :custom_signature, class_name: 'ESP::CustomSignature'
7
+ has_many :results, class_name: 'ESP::CustomSignature::Result'
8
+
9
+ def activate
10
+ patch(:activate).tap do |response|
11
+ load_attributes_from_response(response)
12
+ end
13
+ rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess => error
14
+ load_remote_errors(error, true)
15
+ self.code = error.response.code
16
+ false
17
+ end
18
+
19
+ def archive
20
+ patch(:archive).tap do |response|
21
+ load_attributes_from_response(response)
22
+ end
23
+ rescue ActiveResource::BadRequest, ActiveResource::ResourceInvalid, ActiveResource::UnauthorizedAccess => error
24
+ load_remote_errors(error, true)
25
+ self.code = error.response.code
26
+ false
27
+ end
28
+
29
+ # :singleton-method: where
30
+ # Return a paginated CustomSignature::Definition list filtered by search parameters
31
+ #
32
+ # ==== Parameters
33
+ #
34
+ # +clauses+ | Hash of attributes with appended predicates to search, sort and include.
35
+ #
36
+ # ===== Valid Clauses
37
+ #
38
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-definition-attributes] for valid arguments
39
+ #
40
+ # :call-seq:
41
+ # where(clauses = {})
42
+
43
+ ##
44
+ # :singleton-method: find
45
+ # Find a CustomSignature::Definition by id
46
+ #
47
+ # ==== Parameter
48
+ #
49
+ # +id+ | Required | The ID of the custom signature definition to retrieve
50
+ #
51
+ # +options+ | Optional | A hash of options
52
+ #
53
+ # ===== Valid Options
54
+ #
55
+ # +include+ | The list of associated objects to return on the initial request.
56
+ #
57
+ # ===== Valid Includable Associations
58
+ #
59
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-definition-attributes] for valid arguments
60
+ #
61
+ # :call-seq:
62
+ # find(id, options = {})
63
+
64
+ # :singleton-method: all
65
+ # Return a paginated CustomSignature::Definition list
66
+
67
+ # :singleton-method: create
68
+ # Create a CustomSignature::Definition
69
+ # :call-seq:
70
+ # create(attributes={})
71
+ #
72
+ # ==== Parameter
73
+ #
74
+ # +attributes+ | Required | A hash of custom signature definition attributes
75
+ #
76
+ # ===== Valid Attributes
77
+ #
78
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-definition-create] for valid arguments
79
+ #
80
+ # ==== Example
81
+ #
82
+ # definition = ESP::CustomSignature::Definition.create(custom_signature_id: 1)
83
+
84
+ # :method: save
85
+ # Create or update a CustomSignature::Definition
86
+ #
87
+ # ===== Valid Attributes
88
+ #
89
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-definition-create] for valid arguments
90
+ #
91
+ # ==== Example
92
+ #
93
+ # definition = ESP::CustomSignature::Definition.new(custom_signature_id: 1)
94
+ # definition.save
95
+
96
+ # :method: destroy
97
+ # Delete a CustomSignature::Definition
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,97 @@
1
+ module ESP
2
+ class CustomSignature
3
+ class Result < ESP::Resource
4
+ autoload :Alert, File.expand_path(File.dirname(__FILE__) + '/result/alert')
5
+
6
+ self.prefix += "custom_signature_"
7
+
8
+ belongs_to :definition, class_name: 'ESP::CustomSignature::Definition', foreign_key: :definition_id
9
+ belongs_to :region, class_name: 'ESP::Region'
10
+ belongs_to :external_account, class_name: 'ESP::ExternalAccount'
11
+
12
+ def alerts
13
+ return attributes['alerts'] if attributes['alerts'].present?
14
+ CustomSignature::Result::Alert.for_result(id)
15
+ end
16
+
17
+ # Not Implemented. You cannot update a CustomSignature::Result.
18
+ def update
19
+ fail ESP::NotImplementedError
20
+ end
21
+
22
+ # Not Implemented. You cannot destroy a CustomSignature::Result.
23
+ def destroy
24
+ fail ESP::NotImplementedError
25
+ end
26
+
27
+ # :singleton-method: where
28
+ # Return a paginated CustomSignature::Result list filtered by search parameters
29
+ #
30
+ # ==== Parameters
31
+ #
32
+ # +clauses+ | Hash of attributes with appended predicates to search, sort and include.
33
+ #
34
+ # ===== Valid Clauses
35
+ #
36
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-result-attributes] for valid arguments
37
+ #
38
+ # :call-seq:
39
+ # where(clauses = {})
40
+
41
+ ##
42
+ # :singleton-method: find
43
+ # Find a CustomSignature::Result by id
44
+ #
45
+ # ==== Parameter
46
+ #
47
+ # +id+ | Required | The ID of the custom signature result to retrieve
48
+ #
49
+ # +options+ | Optional | A hash of options
50
+ #
51
+ # ===== Valid Options
52
+ #
53
+ # +include+ | The list of associated objects to return on the initial request.
54
+ #
55
+ # ===== Valid Includable Associations
56
+ #
57
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-result-attributes] for valid arguments
58
+ #
59
+ # :call-seq:
60
+ # find(id, options = {})
61
+
62
+ # :singleton-method: all
63
+ # Return a paginated CustomSignature::Result list
64
+
65
+ # :singleton-method: create
66
+ # Create a CustomSignature::Result
67
+ # :call-seq:
68
+ # create(attributes={})
69
+ #
70
+ # ==== Parameter
71
+ #
72
+ # +attributes+ | Required | A hash of custom signature result attributes
73
+ #
74
+ # ===== Valid Attributes
75
+ #
76
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-result-create] for valid arguments
77
+ #
78
+ # ==== Example
79
+ #
80
+ # signature = "# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: 'count == 0')\r\n else\r\n pass(user_count: count, condition: 'count >= 1')\r\n end\r\nend\r\n"
81
+ # result = ESP::CustomSignature::Result.create(signature: signature, language: "ruby", region_id: 1, external_account_id: 1)
82
+
83
+ # :method: save
84
+ # Create or update a CustomSignature::Result
85
+ #
86
+ # ===== Valid Attributes
87
+ #
88
+ # See {API documentation}[http://api-docs.evident.io?ruby#custom-signature-result-create] for valid arguments
89
+ #
90
+ # ==== Example
91
+ #
92
+ # signature = "# Demo Ruby Signature\r\nconfigure do |c|\r\n # Set regions to run in. Remove this line to run in all regions.\r\n c.valid_regions = [:us_east_1]\r\n # Override region to display as global. Useful when checking resources\r\n # like IAM that do not have a specific region.\r\n c.display_as = :global\r\n # deep_inspection works with set_data to automically collect\r\n # data fields for each alert. Not required.\r\n c.deep_inspection = [:users]\r\nend\r\n\r\n# Required perform method\r\ndef perform(aws)\r\n list_users = aws.iam.list_users\r\n count = list_users[:users].count\r\n\r\n # Set data for deep_inspection to use\r\n set_data(list_users)\r\n\r\n if count == 0\r\n fail(user_count: count, condition: 'count == 0')\r\n else\r\n pass(user_count: count, condition: 'count >= 1')\r\n end\r\nend\r\n"
93
+ # result = ESP::CustomSignature::Result.new(signature: signature, language: "ruby", region_id: 1, external_account_id: 1)
94
+ # result.save
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,53 @@
1
+ module ESP
2
+ class CustomSignature
3
+ class Result
4
+ class Alert < ESP::Resource
5
+ belongs_to :region, class_name: 'ESP::Region'
6
+ belongs_to :external_account, class_name: 'ESP::ExternalAccount'
7
+ belongs_to :custom_signature, class_name: 'ESP::CustomSignature'
8
+
9
+ # Returns all the alerts for a custom signature result identified by the custom_signature_result_id parameter.
10
+ #
11
+ # ==== Parameters
12
+ #
13
+ # +custom_signature_result_id+ | Required | The ID of the custom signature result to retrieve alerts for
14
+ #
15
+ # See {API documentation}[http://api-docs.evident.io?ruby#alert-attributes] for valid arguments
16
+ def self.for_result(custom_signature_result_id = nil)
17
+ fail ArgumentError, "You must supply a custom signature result id." unless custom_signature_result_id.present?
18
+ # call find_every directly since find is overriden/not implemented
19
+ find_every(from: "#{prefix}custom_signature_results/#{custom_signature_result_id}/alerts.json")
20
+ end
21
+
22
+ # Not Implemented. You cannot search for CustomSignature::Result::Alert.
23
+ #
24
+ # Regular ARELlike methods are disabled.
25
+ def self.find(*)
26
+ fail ESP::NotImplementedError, 'Regular ARELlike methods are disabled. Use the .for_result method.'
27
+ end
28
+
29
+ # Not Implemented. You cannot search for CustomSignature::Result::Alert.
30
+ #
31
+ # Regular ARELlike methods are disabled.
32
+ def self.where(*)
33
+ fail ESP::NotImplementedError, 'Regular ARELlike methods are disabled. Use the .for_result method.'
34
+ end
35
+
36
+ # Not Implemented. You cannot create a CustomSignature::Result::Alert.
37
+ def create
38
+ fail ESP::NotImplementedError
39
+ end
40
+
41
+ # Not Implemented. You cannot update a CustomSignature::Result::Alert.
42
+ def update
43
+ fail ESP::NotImplementedError
44
+ end
45
+
46
+ # Not Implemented. You cannot destroy a CustomSignature::Result::Alert.
47
+ def destroy
48
+ fail ESP::NotImplementedError
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end