befog 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/bin/befog ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "rubygems"
4
+ require "bundler/setup"
5
+
6
+ # resolve bin path, ignoring symlinks
7
+ require "pathname"
8
+ bin_file = Pathname.new(__FILE__).realpath
9
+
10
+ # add self to libpath
11
+ $:.unshift File.expand_path("../../lib", bin_file)
12
+
13
+ require "befog"
14
+
15
+ Befog::CLI.run(*ARGV)
data/lib/befog.rb ADDED
@@ -0,0 +1 @@
1
+ require "befog/cli"
data/lib/befog/cli.rb ADDED
@@ -0,0 +1,72 @@
1
+ require "befog/commands/add"
2
+ require "befog/commands/remove"
3
+ require "befog/commands/start"
4
+ require "befog/commands/stop"
5
+ require "befog/commands/run"
6
+ require "befog/commands/list"
7
+ require "befog/commands/configure"
8
+
9
+ module Befog
10
+ module CLI
11
+
12
+ COMMANDS = {
13
+ "add" => Befog::Commands::Add,
14
+ "remove" => Befog::Commands::Remove,
15
+ "start" => Befog::Commands::Start,
16
+ "stop" => Befog::Commands::Stop,
17
+ "run" => Befog::Commands::Run,
18
+ "list" => Befog::Commands::List,
19
+ "ls" => Befog::Commands::List,
20
+ "configure" => Befog::Commands::Configure,
21
+ "config" => Befog::Commands::Configure
22
+ }
23
+
24
+ def self.run(subcommand=nil,*args)
25
+ if command = COMMANDS[subcommand]
26
+ begin
27
+ command.run(args)
28
+
29
+ # TODO: use a befog-specific error class to
30
+ # differentiate between expected exceptions
31
+ # (just display the error message) and un-
32
+ # expected (display the backtrace)
33
+ rescue => e
34
+ $stderr.puts "befog: #{e.message}"
35
+ $stderr.puts e.backtrace
36
+ exit(-1)
37
+ end
38
+ else
39
+ if subcommand
40
+ usage "'#{subcommand}' is not a supported command"
41
+ else
42
+ usage "No subcommand provided."
43
+ end
44
+ end
45
+ end
46
+
47
+ def self.usage(message)
48
+ $stderr.puts "befog: #{message}"
49
+ $stderr.puts <<-eos
50
+
51
+ Usage: befog <subcommand> [<bank>] [<options>]
52
+
53
+ The befog command allows you to manage your cloud servers from the command line.
54
+
55
+ Valid commands:
56
+
57
+ configure, Configure a bank of servers
58
+ config
59
+ add Provision new servers for a bank of servers
60
+ remove De-provision servers for a bank of servers
61
+ start Start a bank of servers
62
+ stop Stop (suspend) a bank of servers
63
+ run Run a command on each of a bank of servers
64
+ list,ls List all servers with optional bank, region, or provider
65
+
66
+ You can get more options for any command with --help or -h.
67
+ eos
68
+ exit(-1)
69
+
70
+ end
71
+ end
72
+ end
@@ -0,0 +1 @@
1
+ require "befog/commands/cli"
@@ -0,0 +1,55 @@
1
+ require "befog/commands/mixins/command"
2
+ require "befog/commands/mixins/configurable"
3
+ require "befog/commands/mixins/bank"
4
+ require "befog/commands/mixins/provider"
5
+ require "befog/commands/mixins/help"
6
+
7
+ module Befog
8
+ module Commands
9
+
10
+ class Add
11
+
12
+ include Mixins::Command
13
+ include Mixins::Configurable
14
+ include Mixins::Bank
15
+ include Mixins::Provider
16
+ include Mixins::Help
17
+
18
+
19
+ command "befog add <bank>",
20
+ :default_to_help => true
21
+
22
+ option :count,
23
+ :short => "-c COUNT",
24
+ :long => "--count COUNT",
25
+ :required => true,
26
+ :description => "The number of machines to provision"
27
+
28
+ # TODO: Add support for machine type
29
+
30
+ def run
31
+ count = options[:count].to_i
32
+ if count <= 0
33
+ $stderr.puts "Number must be an integer greater than 0."
34
+ return
35
+ end
36
+ servers = []
37
+ count.times do |i|
38
+ $stdout.puts "Provisioning server #{i+1} ..."
39
+ # TODO: Figure out how to give the server a name
40
+ servers << compute.servers.create(:image_id => bank["image"],
41
+ :key_name => bank["keypair"], :region => bank["region"])
42
+ end
43
+ $stdout.puts "This may take a few minutes ..."
44
+ servers.each do |server|
45
+ server.wait_for { $stdout.puts "Still working ..." ; ready? }
46
+ self.servers << server.id
47
+ end
48
+ servers.each do |server|
49
+ $stdout.puts "Server #{server.id} is ready at #{server.dns_name}."
50
+ end
51
+ save
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,80 @@
1
+ require "befog/commands/mixins/command"
2
+ require "befog/commands/mixins/configurable"
3
+ require "befog/commands/mixins/provider"
4
+ require "befog/commands/mixins/bank"
5
+ require "befog/commands/mixins/help"
6
+
7
+ module Befog
8
+
9
+ module Commands
10
+
11
+ class Configure
12
+
13
+ include Mixins::Command
14
+ include Mixins::Configurable
15
+ include Mixins::Provider
16
+ include Mixins::Bank
17
+ include Mixins::Help
18
+
19
+ command "befog configure [<bank>]",
20
+ :default_to_help => true
21
+
22
+ option :key,
23
+ :short => "-k KEY",
24
+ :long => "--key KEY",
25
+ :description => "Your account key"
26
+
27
+ option :secret,
28
+ :short => "-s SECRET",
29
+ :long => "--secret SECRET",
30
+ :description => "Your account secret"
31
+
32
+ option :provider,
33
+ :short => "-q PROVIDER",
34
+ :long => "--provider PROVIDER",
35
+ :description => "The provider provisioning a bank of servers"
36
+
37
+ option :region,
38
+ :short => "-r REGION",
39
+ :long => "--region REGION",
40
+ :description => "The region (datacenter) where a bank is provisioned"
41
+
42
+ option :image,
43
+ :short => "-i IMAGE",
44
+ :long => "--image IMAGE",
45
+ :description => "The image for provisioning pods"
46
+
47
+ option :keypair,
48
+ :short => "-x KEYPAIR",
49
+ :long => "--keypair KEYPAIR",
50
+ :description => "The keypair name to use with SSH"
51
+
52
+ option :group,
53
+ :short => "-g GROUP",
54
+ :long => "--group GROUP",
55
+ :description => "The security group to use for new instances"
56
+
57
+ def self.run(args)
58
+ self.new(args).run
59
+ end
60
+
61
+ def initialize(arguments)
62
+ process_arguments(arguments)
63
+ end
64
+
65
+ def run
66
+ %w( key secret ).each do |key|
67
+ _key = key.to_sym
68
+ provider[key] = options[_key] if options[_key]
69
+ end
70
+ if options[:bank]
71
+ %w( provider region image keypair group ).each do |key|
72
+ _key = key.to_sym
73
+ bank[key] = options[_key] if options[_key]
74
+ end
75
+ end
76
+ save
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,76 @@
1
+ require "fog"
2
+ require "befog/commands/mixins/command"
3
+ require "befog/commands/mixins/configurable"
4
+ require "befog/commands/mixins/bank"
5
+ require "befog/commands/mixins/provider"
6
+ require "befog/commands/mixins/server"
7
+ require "befog/commands/mixins/help"
8
+
9
+ module Befog
10
+ module Commands
11
+
12
+ class List
13
+
14
+ include Mixins::Command
15
+ include Mixins::Configurable
16
+ include Mixins::Bank
17
+ include Mixins::Provider
18
+ include Mixins::Server
19
+ include Mixins::Help
20
+
21
+ command "befog list [<bank>]",
22
+ :default_to_help => false
23
+
24
+ option :provider,
25
+ :short => "-q PROVIDER",
26
+ :long => "--provider PROVIDER",
27
+ :description => "The provider provisioning a bank of servers"
28
+
29
+
30
+ def run
31
+ if options[:bank]
32
+ list_bank(options[:bank])
33
+ elsif options[:provider]
34
+ list_provider(options[:provider])
35
+ else
36
+ list_all
37
+ end
38
+ end
39
+
40
+ def list_all
41
+ $stdout.puts "All Servers"
42
+ banks.keys.select do |name|
43
+ list_bank(name)
44
+ end
45
+ end
46
+
47
+ def list_provider(provider,indent="")
48
+ $stdout.puts "#{indent}- Provider: #{provider}"
49
+ indent += " "
50
+ banks.select do |name,b|
51
+ if b["configuration"] and b["configuration"]["provider"] == provider
52
+ list_bank(name,indent)
53
+ end
54
+ end
55
+ end
56
+
57
+ def list_bank(name, indent="")
58
+ out = []
59
+ out << "#{indent}- Bank: #{name}"
60
+ indent += " "
61
+ configuration = banks[name]["configuration"]
62
+ out += %w( provider region image keypair type ).reduce([]) do |rval,key|
63
+ rval << "#{key}: #{configuration[key]}" unless configuration[key].nil?
64
+ rval
65
+ end
66
+ out << "instances:"
67
+ banks[name]["servers"].each do |id|
68
+ c = compute(configuration["provider"])
69
+ out << "- #{c.servers.get(id).public_ip_address}"
70
+ end
71
+ $stdout.puts out.join("\n#{indent}")
72
+ end
73
+
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,50 @@
1
+ module Befog
2
+ module Commands
3
+ module Mixins
4
+ module Bank
5
+
6
+ def banks
7
+ configuration["banks"] ||= {}
8
+ end
9
+
10
+ def _bank
11
+ raise "You must specify a bank to do this" unless options[:bank]
12
+ banks[options[:bank]] ||= {}
13
+ end
14
+
15
+ def bank
16
+ _bank["configuration"] ||= {}
17
+ end
18
+
19
+ def servers
20
+ _bank["servers"] ||= []
21
+ end
22
+
23
+ def process_arguments(arguments)
24
+ _bank,*rest = arguments
25
+ if _bank =~ /^\-/ or rest.empty?
26
+ super
27
+ else
28
+ super(rest)
29
+ options[:bank] = _bank
30
+ bank.each do |key,value|
31
+ options[key.to_sym] = value
32
+ end
33
+ end
34
+ end
35
+
36
+ def run_for_each_server
37
+ if servers.empty?
38
+ $stderr.puts "No servers are in bank '#{options[:bank]}'."
39
+ return
40
+ end
41
+ servers.each do |id|
42
+ run_for_server(id)
43
+ end
44
+ end
45
+
46
+ end
47
+ end
48
+ end
49
+ end
50
+
@@ -0,0 +1,80 @@
1
+ require "optparse"
2
+
3
+ module Befog
4
+ module Commands
5
+ module Mixins
6
+ module Command
7
+
8
+ def self.included(target)
9
+ target.module_eval do
10
+
11
+ class << self
12
+
13
+ def command(name,descriptor)
14
+ @command = (Struct.new(:name,:descriptor)).new(name,descriptor)
15
+ end
16
+
17
+ def option(name,descriptor)
18
+ options << [name,descriptor]
19
+ end
20
+
21
+ def options ; @options||=[] ; end
22
+
23
+ # TODO: Support multi-line descriptions?
24
+ def process_arguments(arguments)
25
+ results = {}; required = []
26
+ parser = OptionParser.new do |parser|
27
+ parser.banner = "Usage: #{@command.name} [options]"
28
+ options.each do |name,descriptor|
29
+ if descriptor[:help]
30
+ parser.on_tail(*descriptor.values_at(:short,:long,:description)) do |value|
31
+ $stdout.puts parser
32
+ exit(0)
33
+ end
34
+ else
35
+ results[name] = descriptor[:default] if descriptor[:default]
36
+ required << name if descriptor[:required]
37
+ parser.on(*descriptor.values_at(:short,:long,:description)) do |value|
38
+ results[name] = value
39
+ end
40
+ end
41
+ end
42
+ end
43
+ if @command.descriptor[:default_to_help] and arguments.empty?
44
+ $stdout.puts parser
45
+ exit(0)
46
+ end
47
+ parser.parse!(arguments)
48
+ required.each do |name|
49
+ unless results[name]
50
+ $stderr.puts "Missing required option '#{name}'"
51
+ $stderr.puts parser
52
+ exit(-1)
53
+ end
54
+ end
55
+ results
56
+ end
57
+
58
+ def run(arguments)
59
+ new(arguments).run
60
+ end
61
+
62
+ end
63
+
64
+ end
65
+ end
66
+
67
+ attr_reader :options
68
+
69
+ def initialize(arguments)
70
+ process_arguments(arguments)
71
+ end
72
+
73
+ def process_arguments(arguments)
74
+ @options = self.class.process_arguments(arguments)
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end
80
+
@@ -0,0 +1,45 @@
1
+ module Befog
2
+ module Commands
3
+ module Mixins
4
+ module Configurable
5
+
6
+ def self.included(target)
7
+
8
+ target.module_eval do
9
+
10
+ option :path,
11
+ :short => "-p PATH",
12
+ :long => "--path PATH",
13
+ :default => "~/.befog",
14
+ :description => "Path to the configuration file you want to use (defaults to '~/.befog')"
15
+
16
+ option :name,
17
+ :short => "-n NAME",
18
+ :long => "--name NAME",
19
+ :default => "default",
20
+ :description => "The name of this configuration (defaults to 'default')"
21
+
22
+ end
23
+ end
24
+
25
+ def configuration_path
26
+ @configuration_path = File.expand_path(options[:path])
27
+ end
28
+
29
+ def _configuration
30
+ @configuration ||= (YAML.load_file(configuration_path) rescue {})
31
+ end
32
+
33
+ def configuration
34
+ _configuration[options[:name]] ||= {}
35
+ end
36
+
37
+ def save
38
+ File.open(File.expand_path(configuration_path),"w") { |f| YAML.dump(_configuration,f) }
39
+ end
40
+
41
+
42
+ end
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,19 @@
1
+ module Befog
2
+ module Commands
3
+ module Mixins
4
+ module Help
5
+ def self.included(target)
6
+ target.module_eval do
7
+ option :help,
8
+ :short => "-h",
9
+ :long => "--help",
10
+ :description => "Show this message",
11
+ :help => true
12
+ end
13
+ end
14
+
15
+ end
16
+ end
17
+ end
18
+ end
19
+
@@ -0,0 +1,40 @@
1
+ require "befog/providers/aws"
2
+
3
+ module Befog
4
+ module Commands
5
+ module Mixins
6
+ module Provider
7
+
8
+ PROVIDERS = {
9
+ "aws" => Befog::Providers::AWS
10
+ }
11
+
12
+ def providers
13
+ configuration["providers"] ||= {}
14
+ end
15
+
16
+ def provider
17
+ raise "You must specify a provider (with --provider or -q) to do this" unless options[:provider]
18
+ providers[options[:provider]] ||= {}
19
+ end
20
+
21
+ def regions
22
+ provider["regions"] ||= {}
23
+ end
24
+
25
+ def region
26
+ raise "Please set the region using -r or --region." unless options[:region]
27
+ regions[options[:region]] ||= {}
28
+ end
29
+
30
+ def compute(provider=nil)
31
+ provider ||= options[:provider]
32
+ @compute ||= PROVIDERS[provider].compute(providers[provider])
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
39
+
40
+
@@ -0,0 +1,13 @@
1
+ module Befog
2
+ module Commands
3
+ module Mixins
4
+ module Server
5
+
6
+ def get_server(id)
7
+ compute.servers.get(id)
8
+ end
9
+
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,57 @@
1
+ require "befog/commands/mixins/command"
2
+ require "befog/commands/mixins/configurable"
3
+ require "befog/commands/mixins/bank"
4
+ require "befog/commands/mixins/provider"
5
+ require "befog/commands/mixins/server"
6
+ require "befog/commands/mixins/help"
7
+
8
+ module Befog
9
+ module Commands
10
+
11
+ class Remove
12
+
13
+ include Mixins::Command
14
+ include Mixins::Configurable
15
+ include Mixins::Bank
16
+ include Mixins::Provider
17
+ include Mixins::Server
18
+ include Mixins::Help
19
+
20
+ command "befog remove <bank>",
21
+ :default_to_help => true
22
+
23
+ option :count,
24
+ :short => "-c COUNT",
25
+ :long => "--count COUNT",
26
+ :required => true,
27
+ :description => "The number of machines to de-provision"
28
+
29
+ def run
30
+ if servers.empty?
31
+ $stderr.puts "No servers are in bank '#{name}'."
32
+ return
33
+ end
34
+ count = options[:count].to_i
35
+ if count <= 0
36
+ $stderr.puts "Number must be an integer greater than 0."
37
+ return
38
+ end
39
+ if count > servers.size
40
+ $stderr.puts "Number must be less than or equal to the bank size of #{bank.size}."
41
+ return
42
+ end
43
+ count.times do |i|
44
+ id = servers.pop
45
+ $stdout.puts "Deprovisioning server #{id} ..."
46
+ begin
47
+ get_server(id).destroy
48
+ rescue => e
49
+ $stderr.puts "Error deprovisioning server #{id}"
50
+ servers.push id
51
+ end
52
+ save
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,45 @@
1
+ require "fog"
2
+ require "befog/commands/mixins/command"
3
+ require "befog/commands/mixins/configurable"
4
+ require "befog/commands/mixins/bank"
5
+ require "befog/commands/mixins/provider"
6
+ require "befog/commands/mixins/server"
7
+ require "befog/commands/mixins/help"
8
+
9
+
10
+ module Befog
11
+ module Commands
12
+
13
+ class Run
14
+
15
+ include Mixins::Command
16
+ include Mixins::Configurable
17
+ include Mixins::Bank
18
+ include Mixins::Provider
19
+ include Mixins::Server
20
+ include Mixins::Help
21
+
22
+ command "befog run <bank>",
23
+ :default_to_help => true
24
+
25
+ option :command,
26
+ :short => "-c COMMAND",
27
+ :long => "--command COMMAND",
28
+ :required => true,
29
+ :description => "Command to run (required)"
30
+
31
+ def run
32
+ run_for_each_server
33
+ end
34
+
35
+ def run_for_server(id)
36
+ address = get_server(id).public_ip_address
37
+ $stdout.puts "Running command '#{options[:command]}' for #{address} ..."
38
+ result = Fog::SSH.new(address, "root").run(options[:command]).first
39
+ $stdout.puts "[#{address}: STDOUT] #{result.stdout}"
40
+ $stderr.puts "[#{address}: STDERR] #{result.stderr}"
41
+ end
42
+
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,33 @@
1
+ require "fog"
2
+ require "befog/commands/mixins/command"
3
+ require "befog/commands/mixins/configurable"
4
+ require "befog/commands/mixins/bank"
5
+ require "befog/commands/mixins/provider"
6
+ require "befog/commands/mixins/server"
7
+ require "befog/commands/mixins/help"
8
+
9
+ module Befog
10
+ module Commands
11
+
12
+ class Start
13
+
14
+ include Mixins::Command
15
+ include Mixins::Configurable
16
+ include Mixins::Bank
17
+ include Mixins::Provider
18
+ include Mixins::Server
19
+ include Mixins::Help
20
+
21
+ command "befog start <bank>",
22
+ :default_to_help => true
23
+
24
+ def run
25
+ run_for_each_server
26
+ end
27
+
28
+ def run_for_server(id)
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,34 @@
1
+ require "fog"
2
+ require "befog/commands/mixins/command"
3
+ require "befog/commands/mixins/configurable"
4
+ require "befog/commands/mixins/bank"
5
+ require "befog/commands/mixins/provider"
6
+ require "befog/commands/mixins/server"
7
+ require "befog/commands/mixins/help"
8
+
9
+ module Befog
10
+ module Commands
11
+
12
+
13
+ class Stop
14
+
15
+ include Mixins::Command
16
+ include Mixins::Configurable
17
+ include Mixins::Bank
18
+ include Mixins::Provider
19
+ include Mixins::Server
20
+ include Mixins::Help
21
+
22
+ command "befog stop <bank>",
23
+ :default_to_help => true
24
+
25
+ def run
26
+ run_for_each_server
27
+ end
28
+
29
+ def run_for_server(id)
30
+ end
31
+
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,20 @@
1
+ require "fog"
2
+ Excon.defaults[:ssl_verify_peer] = false
3
+
4
+ module Befog
5
+
6
+ module Providers
7
+
8
+ class AWS
9
+
10
+ def self.compute(configuration)
11
+ Fog::Compute.new(:provider => "AWS",
12
+ :aws_access_key_id => configuration["key"],
13
+ :aws_secret_access_key => configuration["secret"])
14
+ end
15
+
16
+ end
17
+
18
+ end
19
+
20
+ end
metadata ADDED
@@ -0,0 +1,132 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: befog
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Carlo Flores carlo@spire.io
14
+ - Dan Yoder dan@spire.io
15
+ autorequire:
16
+ bindir: bin
17
+ cert_chain: []
18
+
19
+ date: 2012-04-03 00:00:00 Z
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: fog
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ hash: 23
30
+ segments:
31
+ - 1
32
+ - 1
33
+ - 2
34
+ version: 1.1.2
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ - !ruby/object:Gem::Dependency
38
+ name: rspec
39
+ prerelease: false
40
+ requirement: &id002 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ hash: 13
46
+ segments:
47
+ - 2
48
+ - 7
49
+ version: "2.7"
50
+ type: :development
51
+ version_requirements: *id002
52
+ - !ruby/object:Gem::Dependency
53
+ name: yard
54
+ prerelease: false
55
+ requirement: &id003 !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ~>
59
+ - !ruby/object:Gem::Version
60
+ hash: 5
61
+ segments:
62
+ - 0
63
+ - 7
64
+ version: "0.7"
65
+ type: :development
66
+ version_requirements: *id003
67
+ description: "\t\tThe befog gem allows you to manage your cloud servers\n\
68
+ \t\tdirectly from the command-line. \n"
69
+ email:
70
+ -
71
+ -
72
+ executables:
73
+ - befog
74
+ extensions: []
75
+
76
+ extra_rdoc_files: []
77
+
78
+ files:
79
+ - lib/befog/cli.rb
80
+ - lib/befog/commands/add.rb
81
+ - lib/befog/commands/configure.rb
82
+ - lib/befog/commands/list.rb
83
+ - lib/befog/commands/mixins/bank.rb
84
+ - lib/befog/commands/mixins/command.rb
85
+ - lib/befog/commands/mixins/configurable.rb
86
+ - lib/befog/commands/mixins/help.rb
87
+ - lib/befog/commands/mixins/provider.rb
88
+ - lib/befog/commands/mixins/server.rb
89
+ - lib/befog/commands/remove.rb
90
+ - lib/befog/commands/run.rb
91
+ - lib/befog/commands/start.rb
92
+ - lib/befog/commands/stop.rb
93
+ - lib/befog/commands.rb
94
+ - lib/befog/providers/aws.rb
95
+ - lib/befog.rb
96
+ - bin/befog
97
+ homepage: https://github.com/spire-io/befog
98
+ licenses: []
99
+
100
+ post_install_message:
101
+ rdoc_options: []
102
+
103
+ require_paths:
104
+ - lib
105
+ required_ruby_version: !ruby/object:Gem::Requirement
106
+ none: false
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ hash: 3
111
+ segments:
112
+ - 0
113
+ version: "0"
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ hash: 3
120
+ segments:
121
+ - 0
122
+ version: "0"
123
+ requirements: []
124
+
125
+ rubyforge_project:
126
+ rubygems_version: 1.8.11
127
+ signing_key:
128
+ specification_version: 3
129
+ summary: Cloud provisioning CLI
130
+ test_files: []
131
+
132
+ has_rdoc: