Parent

OpenShift::FrontendProxyServer

Frontend Proxy Server

Represents the front-end proxy server on the system. Upon initialization, defaults necessary to compute ranges are extracted from Openshift::Config.

Note: This is the HAProxy implementation; other implementations may vary.

Public Class Methods

new() click to toggle source
# File lib/openshift-origin-node/model/frontend_proxy.rb, line 50
def initialize
  # Extract config values and compute the port range this proxy
  # instance should act upon, relative to the given container/user.
  config = OpenShift::Config.new

  @port_begin = (config.get("PORT_BEGIN") || "35531").to_i
  @ports_per_user = (config.get("PORTS_PER_USER") || "5").to_i
  @uid_begin = (config.get("UID_BEGIN") || "500").to_i
end

Public Instance Methods

add(uid, ip, port) click to toggle source

Adds a new proxy mapping for the specified UID, IP and target port using the next available proxy port in the user's range.

Returns an Integer value for the mapped proxy port on success. Raises a FrontendProxyServerException if the mapping attempt fails or if no ports are left available to map.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 156
def add(uid, ip, port)
  raise "No UID specified" if uid == nil
  raise "No IP specified" if ip == nil
  raise "No port specified" if port == nil
  raise "Invalid port specified" unless port.is_a? Integer

  requested_addr = "#{ip}:#{port}"

  port_range(uid).each do |proxy_port|
    # Get the existing mapped address for this proxy port
    current_addr = system_proxy_show(proxy_port)

    # If there's already a mapping for this proxy port, return
    # the existing mapping if it matches the request, otherwise
    # skip it as being already in use
    if current_addr != nil
      if current_addr == requested_addr
        return proxy_port
      else
        next
      end
    end

    # No existing mapping exists, so attempt to create one
    out, err, rc = system_proxy_set({:proxy_port => proxy_port, :addr => requested_addr})
    
    if rc != 0
      raise FrontendProxyServerException.new(
        "System proxy set for #{proxy_port}=>#{requested_addr} failed(#{rc}): stdout: #{out} stderr: #{err}", uid)
    end

    return proxy_port
  end

  raise FrontendProxyServerException.new("No ports were left available to map #{requested_addr}", uid)
end
delete(uid, ip, port) click to toggle source

Deletes an existing proxy mapping for the specified UID, IP and port.

Returns nil on success or a FrontendProxyServerException on failure.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 89
def delete(uid, ip, port)
  raise "No UID specified" if uid == nil
  raise "No IP specified" if ip == nil
  raise "No port specified" if port == nil
  raise "Invalid port specified" unless port.is_a? Integer

  target_addr = "#{ip}:#{port}"

  mapped_proxy_port = find_mapped_proxy_port(uid, ip, port)

  # No existing mapping, nothing to do.
  return if mapped_proxy_port == nil

  out, err, rc = system_proxy_delete(mapped_proxy_port)

  if rc != 0
    raise FrontendProxyServerException.new(
      "System proxy failed to delete #{mapped_proxy_port} => #{target_addr}(#{rc}): stdout: #{out} stderr: #{err}", uid)
  end
end
delete_all(proxy_ports, ignore_errors=true) click to toggle source

Deletes all proxy ports in the specified array.

If ignore_errors is specified, any delete attempts will be logged and ignored. Otherwise, any exception will be immediately be re-raised.

Returns the exit code from the call to system_proxy_delete if no exception is raised.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 133
def delete_all(proxy_ports, ignore_errors=true)
  raise "No proxy ports specified" if proxy_ports == nil

  out, err, rc = system_proxy_delete(*proxy_ports)

  if (rc != 0)
    message = "System proxy delete of port(s) #{proxy_ports} failed(#{rc}): stdout: #{out} stderr: #{err}"
    if ignore_errors
      logger.warn(message)
    else
      raise FrontendProxyServerException.new(message)
    end
  end

  return rc
end
delete_all_for_uid(uid, ignore_errors=true) click to toggle source

Deletes any existing proxy ports associated with the given UID.

If ignore_errors is specified, any delete attempts will be logged and ignored. Otherwise, any exception will be immediately be re-raised.

Returns nil on success.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 116
def delete_all_for_uid(uid, ignore_errors=true)
  raise "No UID specified" if uid == nil

  proxy_ports = []

  port_range(uid).each { |proxy_port| proxy_ports << proxy_port }

  delete_all(proxy_ports, ignore_errors)
end
find_mapped_proxy_port(uid, ip, port) click to toggle source

Find the proxy port for a given UID, IP and target port.

Examples:

find_mapped_proxy_port(500, '127.0.0.1', 8080)
=> 35531

Returns the proxy port if found, otherwise nil.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 201
def find_mapped_proxy_port(uid, ip, port)
  raise "No UID specified" if uid == nil
  raise "No IP specified" if ip == nil
  raise "No port specified" if port == nil
  raise "Invalid port specified" unless port.is_a? Integer

  target_addr = "#{ip}:#{port}"

  mapped_proxy_port = nil

  port_range(uid).each do |proxy_port|
    current_addr = system_proxy_show(proxy_port)

    if current_addr == target_addr
      mapped_proxy_port = proxy_port
      break
    end
  end

  return mapped_proxy_port
end
port_range(uid) click to toggle source

Returns a Range representing the valid proxy port values for the given UID.

The port proxy range is determined by configuration and must produce identical results to the abstract cartridge provided range.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 73
def port_range(uid)
  if uid >= wrap_uid
    tuid = uid - wrap_uid + @uid_begin
  else
    tuid = uid
  end

  proxy_port_begin = (tuid-@uid_begin) * @ports_per_user + @port_begin
  proxy_port_range = (proxy_port_begin ... (proxy_port_begin + @ports_per_user))

  return proxy_port_range
end
system_proxy_delete(*ports) click to toggle source

System interface to delete one or more proxy entries.

Example:

system_proxy_delete(30000)
=> [out, err, rc]

system_proxy_delete(30000, 30001, 30002)
=> [out, err, rc]
# File lib/openshift-origin-node/model/frontend_proxy.rb, line 232
def system_proxy_delete(*ports)
  if ports != nil && ports.length > 0
    cmd = %{openshift-port-proxy-cfg setproxy}
    ports.each { |port| cmd << " #{port} delete" }
    
    out, err, rc = shellCmd(cmd)
    return out, err, rc
  else
    return 0, nil, nil
  end
end
system_proxy_set(*mappings) click to toggle source

System interface to set a proxy entry. Expects a varargs array of hashes with keys :proxy_port and :addr representing a mapping entry.

Example:

system_proxy_set({:proxy_port => 30000, :addr => "127.0.0.1:8080"})
=> [out, err, rc]

system_proxy_set(
  {:proxy_port => 30000, :addr => "127.0.0.1:8080"},
  {:proxy_port => 30001, :addr => "127.0.0.1:8081"}
)
=> [out, err, rc]
# File lib/openshift-origin-node/model/frontend_proxy.rb, line 258
def system_proxy_set(*mappings)
  if mappings != nil && mappings.length > 0
    cmd = %{openshift-port-proxy-cfg setproxy}
    mappings.each { |mapping| cmd << %{ #{mapping[:proxy_port]} "#{mapping[:addr]}"} }

    out, err, rc = shellCmd(cmd)
    return out, err, rc
  else
    return 0, nil, nil
  end
end
system_proxy_show(proxy_port) click to toggle source

System interface to show an existing proxy entry.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 271
def system_proxy_show(proxy_port)
  raise "No proxy port specified" unless proxy_port != nil

  target, err, rc = shellCmd(%{openshift-port-proxy-cfg showproxy #{proxy_port} | awk '{ print $2 }'})
  target.chomp!

  return target.length > 0 ? target : nil
end
wrap_uid() click to toggle source

Note, due to a mismatch between dev and prod this is intentionally not GEAR_MIN_UID and the range must wrap back around on itself.

# File lib/openshift-origin-node/model/frontend_proxy.rb, line 63
def wrap_uid
  ((65536 - @port_begin) / @ports_per_user) + @uid_begin
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.