Class: VirtualBox::NATForwardedPort

Inherits:
AbstractModel show all
Defined in:
lib/virtualbox/nat_forwarded_port.rb

Overview

When a VM uses NAT as its NIC type, VirtualBox acts like its own private router for all virtual machines. Because of this, the host machine can’t access services within the guest machine. To get around this, NAT supports port forwarding, which allows the guest machine services to be forwarded to some port on the host machine. Port forwarding is done completely through ExtraData, but is a complicated enough procedure that this class was made to faciliate it.

Note: After changing any forwarded ports, the entire VirtualBox process must be restarted completely for them to take effect. When working with the ruby library, this isn’t so much of an issue, but if you have any VMs running, they must all be shut down and restarted.

# Adding a new Forwarded Port

Since forwarded ports rely on being part of a VM, we’re going to assume that ‘vm` points to a VM which has already been found.

port = VirtualBox::NATForwardedPort.new
port.name = "apache" # This can be anything
port.guestport = 80
port.hostport = 8080
vm.network_adapters[0].nat_driver.forwarded_ports << port
port.save # Or vm.save

# Modifying an Existing Forwarded Port

This is assuming that ‘vm` is a local variable storing a VM object which has already been found.

ports = vm.network_adapters[0].nat_driver.forwarded_ports
ports.first.hostport = 1919
vm.save

# Deleting a Forwarded Port

To delete a forwarded port, you simply destroy it like any other model:

ports = vm.network_adapters[0].nat_driver.forwarded_ports
ports.first.destroy

# Attributes and Relationships

Properties of the model are exposed using standard ruby instance methods which are generated on the fly. Because of this, they are not listed below as available instance methods.

These attributes can be accessed and modified via standard ruby-style ‘instance.attribute` and `instance.attribute=` methods. The attributes are listed below.

Relationships are also accessed like attributes but can’t be set. Instead, they are typically references to other objects such as an AttachedDevice which in turn have their own attributes which can be modified.

## Attributes

This is copied directly from the class header, but lists all available attributes. If you don’t understand what this means, read AbstractModel::Attributable.

attribute :parent, :readonly => true
attribute :name
attribute :protocol, :default => "TCP"
attribute :guestport
attribute :hostport

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from AbstractModel

#errors, errors_for_relationship, #existing_record!, #inspect, #lazy_attribute?, #lazy_relationship?, #new_record!, #new_record?, #parent_machine, #populate_attributes, #populate_relationship, #populate_relationships, reload!, #reload!, reload?, reloaded!, #save!, #save_attribute, #save_changed_interface_attributes, #save_interface_attribute, #set_relationship, #write_attribute

Methods included from AbstractModel::Validatable

#__validates_extract_options, #add_error, #clear_errors, #errors, #errors_on, #full_error_messages, #valid?, #validates_format_of, #validates_inclusion_of, #validates_numericality_of, #validates_presence_of

Methods included from AbstractModel::Relatable

#destroy_relationship, #destroy_relationships, #has_relationship?, included, #lazy_relationship?, #loaded_relationship?, #populate_relationship, #populate_relationships, #read_relationship, #relationship_class, #relationship_data, #save_relationship, #save_relationships, #set_relationship

Methods included from AbstractModel::VersionMatcher

#assert_version_match, #split_version, #version_match?

Methods included from AbstractModel::Dirty

#changed?, #changes, #clear_dirty!, #ignore_dirty, #method_missing, #set_dirty!

Methods included from AbstractModel::InterfaceAttributes

#load_interface_attribute, #load_interface_attributes, #save_interface_attribute, #save_interface_attributes, #spec_to_proc

Methods included from AbstractModel::Attributable

#attributes, #has_attribute?, included, #lazy_attribute?, #loaded_attribute?, #populate_attributes, #read_attribute, #readonly_attribute?, #write_attribute

Methods included from Logger

included, #logger, #logger_output=

Constructor Details

#initialize(data = {}) ⇒ NATForwardedPort

Returns a new instance of NATForwardedPort.

Parameters:

  • data (Hash) (defaults to: {})

    The initial attributes to populate.



118
119
120
121
# File 'lib/virtualbox/nat_forwarded_port.rb', line 118

def initialize(data={})
  super()
  populate_attributes(data) if !data.empty?
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class VirtualBox::AbstractModel::Dirty

Class Method Details

.populate_relationship(caller, interface) ⇒ Array<NATForwardedPort>

Populates a relationship with another model.

**This method typically won’t be used except internally.**

Returns:



83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/virtualbox/nat_forwarded_port.rb', line 83

def populate_relationship(caller, interface)
  relation = Proxies::Collection.new(caller)

  interface.redirects.each do |key, value|
    parts = key.split(",")

    port = new({
      :parent => caller,
      :parent_collection => relation,
      :name => parts[0],
      :protocol => COM::Util.versioned_interface(:NATProtocol).index(parts[1]),
      :guestport => parts[5].to_i,
      :hostport => parts[3].to_i
    })

    port.existing_record!

    relation.push(port)
  end

  relation
end

.save_relationship(caller, data) ⇒ Object

Saves the relationship. This simply calls #save on every member of the relationship.

**This method typically won’t be used except internally.**



110
111
112
113
114
# File 'lib/virtualbox/nat_forwarded_port.rb', line 110

def save_relationship(caller, data)
  data.dup.each do |fp|
    fp.save
  end
end

Instance Method Details

#added_to_relationship(proxy) ⇒ Object

Relationship callback when added to a collection. This is automatically called by any relationship collection when this object is added.



166
167
168
169
# File 'lib/virtualbox/nat_forwarded_port.rb', line 166

def added_to_relationship(proxy)
  write_attribute(:parent, proxy.parent)
  write_attribute(:parent_collection, proxy)
end

#destroy(update_collection = true) ⇒ Boolean

Destroys the port forwarding mapping.

Returns:

  • (Boolean)

    True if command was successful, false otherwise.



153
154
155
156
157
158
159
160
161
162
# File 'lib/virtualbox/nat_forwarded_port.rb', line 153

def destroy(update_collection=true)
  return if new_record?
  previous_name = name_changed? ? name_was : name
  parent.modify_engine do |nat|
    nat.remove_redirect(previous_name)
  end
  parent_collection.delete(self, true) if parent_collection && update_collection
  new_record!
  true
end

#saveBoolean

Saves the forwarded port.

Returns:

  • (Boolean)

    True if command was successful, false otherwise.

Raises:



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/virtualbox/nat_forwarded_port.rb', line 136

def save
  return true if !new_record? && !changed?
  raise Exceptions::ValidationFailedException.new(errors) if !valid?
  destroy(false) if !new_record?

  parent.modify_engine do |nat|
    nat.add_redirect(name, protocol, "", hostport, "", guestport)
  end

  clear_dirty!
  existing_record!
  true
end

#validateObject

Validates a forwarded port.



124
125
126
127
128
129
130
131
# File 'lib/virtualbox/nat_forwarded_port.rb', line 124

def validate
  super

  validates_presence_of :parent
  validates_presence_of :name
  validates_presence_of :guestport
  validates_presence_of :hostport
end