class Cyoi::Providers::Clients::FogProviderClient

Attributes

attributes[R]
fog_compute[R]

Public Class Methods

new(attributes) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 10
def initialize(attributes)
  @attributes = attributes.is_a?(Hash) ? ReadWriteSettings.new(attributes) : attributes
  raise "@attributes must be ReadWriteSettings (or Hash)" unless @attributes.is_a?(ReadWriteSettings)
  setup_fog_connection unless attributes.delete("skip_fog_setup")
end

Public Instance Methods

authorize_port_range(sg, port_range, protocol, ip_range) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 177
def authorize_port_range(sg, port_range, protocol, ip_range)
  raise "must implement"
end
cleanup_unused_ip_addresses() click to toggle source

Destroy all IP addresses that aren’t bound to a server

# File lib/cyoi/providers/clients/fog_provider_client.rb, line 97
def cleanup_unused_ip_addresses
  fog_compute.addresses.each do |a|
    unless a.server
      print "Deleting unused IP address #{a.public_ip}... "
      a.destroy
      puts "done"
    end
  end
end
create_blobstore(blobstore_name) click to toggle source

Creates a bucket/object-store/directory/blobstore To be overridden to make the bucket publicly read-only per IaaS.

# File lib/cyoi/providers/clients/fog_provider_client.rb, line 29
def create_blobstore(blobstore_name)
  unless supports_blobstore_service?
    puts "Provider does not support blobstore service"
    false
  else
    print "Creating publicly readable blobstore #{blobstore_name}... "
    blobstore = fog_storage.directories.create(key: blobstore_name)
    puts "done"
    blobstore
  end
rescue Excon::Errors::Forbidden => e
  puts "failed: credentials do not allow blobstore to be created"
  false
rescue Excon::Errors::Conflict => e
  puts "failed: blobstore already exists but owned by someone else"
  false
end
create_key_pair(key_pair_name) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 47
def create_key_pair(key_pair_name)
  print "Acquiring a key pair #{key_pair_name}... "
  key_pair = fog_compute.key_pairs.create(:name => key_pair_name)
  puts "done"
  key_pair
end
create_security_group(security_group_name, description, defns, extra_attributes={}) click to toggle source

Creates or reuses an security group and opens ports.

security_group_name is the name to be created or reused ports is a hash of name/port for ports to open

protocol defaults to TCP You can also use a more verbose ports using the format:

  • 22,

  • { ports: (80..82) },

  • { protocol: “udp”, ports: (60000..60050) }

  • { protocol: “rdp”, ports: (3398..3398), ip_ranges: [ { cidrIp: “196.212.12.34/32” } ] }

In this example,

* TCP 22 will be opened for ssh from any ip_range,
* TCP ports 80, 81, 82 for http from any ip_range,
* UDP 60000 -> 60050 for mosh from any ip_range and
* TCP 3398 for RDP from ip range: 96.212.12.34/32
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 124
def create_security_group(security_group_name, description, defns, extra_attributes={})
  security_groups = fog_compute.security_groups
  sg = security_groups.find do |s|
    if extra_attributes[:vpc_id]
      s.name == security_group_name && s.vpc_id == extra_attributes[:vpc_id]
    else
      s.name == security_group_name
    end
  end

  suffix = extra_attributes[:vpc_id] ? " for the VPC" : ""
  unless sg
    attributes = {name: security_group_name, description: description}.merge(extra_attributes)
    sg = fog_compute.security_groups.create(attributes)
    puts "Created security group #{security_group_name}#{suffix}"
  else
    puts "Reusing security group #{security_group_name}#{suffix}"
  end
  ip_permissions = ip_permissions(sg)
  ports_opened = 0

  # Unnest { ports: 22 } and { ports: { ports: 22..22 }} legacy inputs
  if defns.is_a?(Hash) && defns[:ports].is_a?(Hash)
    defns = defns[:ports]
  end

  # If we are passed an array of ports, preserve that
  if defns.is_a?(Hash) && defns[:ports].is_a?(Array)
    defns = defns[:ports]
  end

  unless defns.is_a?(Array)
    defns = [defns]
  end
  defns.each do |port_defn|
    port_defns = port_defn.is_a?(Array) ? port_defn : [port_defn]
    port_defns.each do |port_defn|
      (protocol, port_range, ip_range) = extract_port_definition(port_defn)
      unless port_open?(ip_permissions, port_range, protocol, ip_range)
        authorize_port_range(sg, port_range, protocol, ip_range)
        puts " -> opened #{security_group_name} ports #{protocol.upcase} #{port_range.min}..#{port_range.max} from IP range #{ip_range}"
        ports_opened += 1
      end
    end
  end
  puts " -> no additional ports opened" if ports_opened == 0
  true
end
delete_key_pair_if_exists(key_pair_name) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 69
def delete_key_pair_if_exists(key_pair_name)
  if fog_key_pair = fog_compute.key_pairs.get(key_pair_name)
    print "Destroying key pair #{key_pair_name}... "
    fog_key_pair.destroy
    puts "done"
  end
end
delete_servers_with_name(name) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 77
def delete_servers_with_name(name)
  fog_compute.servers.select {|s| s.tags["Name"].downcase == name.downcase }.each do |server|
    print "Destroying server #{server.id}... "
    server.destroy
    puts "done"
  end
end
delete_volumes_with_name(name) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 85
def delete_volumes_with_name(name)
  fog_compute.volumes.select do |v|
    volume_name = v.tags["Name"]
    volume_name && volume_name.downcase == name.downcase
  end.each do |volume|
    print "Destroying volume #{volume.id}... "
    volume.destroy
    puts "done"
  end
end
extract_port_definition(port_defn) click to toggle source

Any of the following port_defn can be used: {

ssh: 22,
http: { ports: (80..82) },
mosh: { protocol: "udp", ports: (60000..60050) }
mosh: { protocol: "rdp", ports: (3398..3398), ip_range: "196.212.12.34/32" }

} In this example,

* TCP 22 will be opened for ssh from any ip_range,
* TCP ports 80, 81, 82 for http from any ip_range,
* UDP 60000 -> 60050 for mosh from any ip_range and
* TCP 3398 for RDP from ip range: 96.212.12.34/32
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 197
def extract_port_definition(port_defn)
  protocol = "tcp"
  ip_range = "0.0.0.0/0"
  if port_defn.is_a? Integer
    port_range = (port_defn..port_defn)
  elsif port_defn.is_a? Range
    port_range = port_defn
  elsif port_defn.is_a? Hash
    protocol = port_defn[:protocol] if port_defn[:protocol]
    port_range = port_defn[:ports]  if port_defn[:ports]
    if port_range.is_a? Integer
      port_range = (port_range..port_range)
    end
    ip_range = port_defn[:ip_range] if port_defn[:ip_range]
  end
  [protocol, port_range, ip_range]
end
find_unused_public_ip_address(options={}) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 219
def find_unused_public_ip_address(options={})
  if address = fog_compute.addresses.find { |s| s.server_id.nil? }
    address.public_ip
  end
end
ip_permissions(sg) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 181
def ip_permissions(sg)
  raise "must implement"
end
port_open?(ip_permissions, port_range, protocol, ip_range) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 173
def port_open?(ip_permissions, port_range, protocol, ip_range)
  raise "must implement"
end
provision_or_reuse_public_ip_address(options={}) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 215
def provision_or_reuse_public_ip_address(options={})
  provision_public_ip_address(options) || find_unused_public_ip_address(options)
end
set_resource_name(resource, name) click to toggle source

set_resource_name(fog_server, “inception”) set_resource_name(volume, “inception-root”) set_resource_name(volume, “inception-store”)

# File lib/cyoi/providers/clients/fog_provider_client.rb, line 65
def set_resource_name(resource, name)
  fog_compute.tags.create :key => "Name", :value => name, :resource_id => resource.id
end
setup_fog_connection() click to toggle source

Implement in subclasses

# File lib/cyoi/providers/clients/fog_provider_client.rb, line 17
def setup_fog_connection
end
supports_blobstore_service?() click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 20
def supports_blobstore_service?
  fog_storage
rescue
  false
end
valid_key_pair_fingerprint?(key_pair_name, fingerprint) click to toggle source
# File lib/cyoi/providers/clients/fog_provider_client.rb, line 54
def valid_key_pair_fingerprint?(key_pair_name, fingerprint)
  if fog_key_pair = fog_compute.key_pairs.get(key_pair_name)
    fog_key_pair.fingerprint == fingerprint
  else
    false
  end
end