Class: Nexpose::Service
- Inherits:
-
Object
- Object
- Nexpose::Service
- Defined in:
- lib/nexpose/service.rb
Overview
This class represents each of the /NexposeReport/nodes/node/endpoints/endpoint/services/service elements in the Nexpose Full XML document.
It provides a convenient way to access the information scattered all over the XML in attributes and nested tags.
Instead of providing separate methods for each supported property we rely on Ruby’s #method_missing to do most of the work.
Instance Attribute Summary collapse
-
#endpoint ⇒ Object
Returns the value of attribute endpoint.
-
#xml ⇒ Object
Returns the value of attribute xml.
Instance Method Summary collapse
-
#initialize(xml_node, endpoint: nil) ⇒ Service
constructor
Accepts an XML node from Nokogiri::XML.
-
#method_missing(method, *args) ⇒ Object
This method is invoked by Ruby when a method that is not defined in this instance is called.
-
#respond_to?(method, include_private = false) ⇒ Boolean
This allows external callers (and specs) to check for implemented properties.
-
#supported_tags ⇒ Object
List of supported tags.
-
#tests(*args) ⇒ Object
Convert each ./test/test entry into a simple hash.
Constructor Details
#initialize(xml_node, endpoint: nil) ⇒ Service
Accepts an XML node from Nokogiri::XML.
endpoint - If the Service is instantiated from the Endpoint class (e.g. from <endpoint><services>…) , it will have access to the parent data.
17 18 19 20 |
# File 'lib/nexpose/service.rb', line 17 def initialize(xml_node, endpoint: nil) @xml = xml_node @endpoint = endpoint end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args) ⇒ Object
This method is invoked by Ruby when a method that is not defined in this instance is called.
In our case we inspect the @method@ parameter and try to find the attribute, simple descendent or collection that it maps to in the XML tree.
60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/nexpose/service.rb', line 60 def method_missing(method, *args) # We could remove this check and return nil for any non-recognized tag. # The problem would be that it would make tricky to debug problems with # typos. For instance: <>.potr would return nil instead of raising an # exception unless .include?(method) super return end # First we try the attributes. In Ruby we use snake_case, but in XML # CamelCase is used for some attributes translations_table = {} method_name = translations_table.fetch(method, method.to_s) return xml.attributes[method_name].value if xml.attributes.key?(method_name) # Finally the enumerations: references, tags if ['fingerprints', 'configurations'].include?(method_name) xpath_selector = { 'fingerprints' => './fingerprints/fingerprint', 'configurations' => './configuration/config' }[method_name] xml.xpath(xpath_selector).collect do |xml_item| { text: xml_item.text }.merge( Hash[ xml_item.attributes.collect do |name, xml_attribute| [name.sub(/-/, '_').to_sym, xml_attribute.value] end ] ) end else # nothing found, the tag is valid but not present in this ReportItem return nil end end |
Instance Attribute Details
#endpoint ⇒ Object
Returns the value of attribute endpoint.
11 12 13 |
# File 'lib/nexpose/service.rb', line 11 def endpoint @endpoint end |
#xml ⇒ Object
Returns the value of attribute xml.
11 12 13 |
# File 'lib/nexpose/service.rb', line 11 def xml @xml end |
Instance Method Details
#respond_to?(method, include_private = false) ⇒ Boolean
This allows external callers (and specs) to check for implemented properties
49 50 51 52 |
# File 'lib/nexpose/service.rb', line 49 def respond_to?(method, include_private = false) return true if .include?(method.to_sym) super end |
#supported_tags ⇒ Object
List of supported tags. They can be attributes, simple descendans or collections (e.g. <references/>, <tags/>)
24 25 26 27 28 29 30 31 32 33 34 |
# File 'lib/nexpose/service.rb', line 24 def [ # attributes :name, # simple tags # multiple tags :fingerprints, :configurations, :tests ] end |
#tests(*args) ⇒ Object
Convert each ./test/test entry into a simple hash
37 38 39 40 41 42 43 44 45 |
# File 'lib/nexpose/service.rb', line 37 def tests(*args) xml.xpath('./tests/test').map do |xml_test| # Inject evidence with data from the node xml_test['port'] = endpoint[:port] xml_test['protocol'] = endpoint[:protocol] Nexpose::Test.new(xml_test) end end |