cyoi 0.7.0 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -13
- data/ChangeLog.md +6 -0
- data/cyoi.gemspec +2 -1
- data/lib/cyoi/cli/provider_addresses/address_cli_openstack.rb +48 -1
- data/lib/cyoi/providers/clients/openstack_provider_client.rb +61 -7
- data/lib/cyoi/version.rb +1 -1
- data/spec/support/rspec-fire.rb +9 -0
- data/spec/unit/providers/clients/openstack_provider_client_spec.rb +110 -0
- metadata +42 -24
checksums.yaml
CHANGED
@@ -1,15 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
|
5
|
-
data.tar.gz: !binary |-
|
6
|
-
MDhjN2E4NzE4ODgyOTk5ZDA4ODBhYTgxZWU0MzM4NmZiMjAyMDc3Yg==
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: a3fba8bd87ffbf411952d31cf1c8e9cabfcf8cd0
|
4
|
+
data.tar.gz: 55688a09f5dba6f443ed83330eef6c0bc46349f1
|
7
5
|
SHA512:
|
8
|
-
metadata.gz:
|
9
|
-
|
10
|
-
NGJmYTJjN2ZkOGYwOTcyNzYyZTI3NTI4OTVhNmQ1MTFjNzE3NThlNGZlYmMw
|
11
|
-
Yzc2NTExNTdiZWE3MTBiYWJmZmNkNmQ4MzdiYzY0YTcxMDJlODQ=
|
12
|
-
data.tar.gz: !binary |-
|
13
|
-
NTIzZTEyMWRhMjcyZmEyZDExMDM0MjRhMWJlODlkZDNmNzdhNWY3NWE2MTBl
|
14
|
-
NGExMWQ0NDhiYTZkYmQ2NjgyZjc2MjFjOTIxYTlmYWQ2MzhhYjBjZDk2ZTA1
|
15
|
-
ZWZhOTFjMmJkZThkODMzMjIzMDAwOGE0ZjRiOWNlZTcwODVhMDg=
|
6
|
+
metadata.gz: 6e5c897fccb38b5fb9ded020a03bd5bdb1b28346ec41945d5d63fb4d331b4f2fea8fc1d929a05b06c1484c748c1b83faaec41ee8c95568502174f6fa0fc988e8
|
7
|
+
data.tar.gz: 08208b223d39521fa851a1767716c3e6c4b25242aa46917fb6438c1bc2aeb741217a4284d0121e6aef9630e7120e31d4b6169de04c2fc17f846a194407a9a53e
|
data/ChangeLog.md
CHANGED
@@ -2,6 +2,12 @@
|
|
2
2
|
|
3
3
|
Cyoi (choose-your-own-infrastructure) is a library to ask an end-user to choose an infrastructure (AWS, OpenStack, etc), region, and login credentials.
|
4
4
|
|
5
|
+
## v0.8
|
6
|
+
|
7
|
+
* openstack - detection of nova vs neutron networking
|
8
|
+
* openstack nova - continues to provision a floating IP
|
9
|
+
* openstack neutron - asks to select a subnet and then an available IP
|
10
|
+
|
5
11
|
## v0.7
|
6
12
|
|
7
13
|
* vsphere provising
|
data/cyoi.gemspec
CHANGED
@@ -26,8 +26,9 @@ README
|
|
26
26
|
spec.add_dependency "highline", "~> 1.6"
|
27
27
|
spec.add_dependency "readwritesettings", "~> 3.0"
|
28
28
|
|
29
|
-
spec.add_development_dependency "bundler"
|
29
|
+
spec.add_development_dependency "bundler"
|
30
30
|
spec.add_development_dependency "rake"
|
31
31
|
spec.add_development_dependency "rspec"
|
32
|
+
spec.add_development_dependency "rspec-fire"
|
32
33
|
spec.add_development_dependency "aruba"
|
33
34
|
end
|
@@ -13,7 +13,12 @@ class Cyoi::Cli::Addresses::AddressCliOpenstack
|
|
13
13
|
|
14
14
|
def perform_and_return_attributes
|
15
15
|
unless valid_address?
|
16
|
-
|
16
|
+
if networks?
|
17
|
+
subnet = select_subnet
|
18
|
+
choose_address_from_subnet(subnet)
|
19
|
+
else
|
20
|
+
provision_address
|
21
|
+
end
|
17
22
|
end
|
18
23
|
export_attributes
|
19
24
|
end
|
@@ -39,6 +44,48 @@ class Cyoi::Cli::Addresses::AddressCliOpenstack
|
|
39
44
|
attributes["ip"] = provider_client.provision_public_ip_address
|
40
45
|
puts attributes.ip
|
41
46
|
end
|
47
|
+
|
48
|
+
def networks?
|
49
|
+
provider_client.networks?
|
50
|
+
end
|
51
|
+
|
52
|
+
def select_subnet
|
53
|
+
subnets = provider_client.subnets
|
54
|
+
subnet = if subnets.size == 0
|
55
|
+
$stderr.puts "ERROR: Your OpenStack is configured for Neutron networking but you have not yet created any subnets."
|
56
|
+
exit 1
|
57
|
+
elsif subnets.size == 1
|
58
|
+
subnets.first
|
59
|
+
else
|
60
|
+
hl.choose do |menu|
|
61
|
+
menu.prompt = "Choose a subnet: "
|
62
|
+
# menu.choice("AWS") { "aws" }
|
63
|
+
subnets.each do |subnet|
|
64
|
+
menu.choice("#{pretty_subnet_name(subnet)}") { subnet }
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
attributes["subnet_id"] = subnet.id
|
69
|
+
subnet
|
70
|
+
end
|
71
|
+
|
72
|
+
def choose_address_from_subnet(subnet)
|
73
|
+
default_ip = provider_client.next_available_ip_in_subnet(subnet)
|
74
|
+
puts "\n"
|
75
|
+
ip = hl.ask("Choose IP ") { |q| q.default = default_ip }.to_s
|
76
|
+
attributes["ip"] = ip
|
77
|
+
end
|
78
|
+
|
79
|
+
def pretty_ip_pool_ranges(subnet)
|
80
|
+
ranges = subnet.allocation_pools.map do |pool|
|
81
|
+
"#{pool['start']}-#{pool['end']}"
|
82
|
+
end
|
83
|
+
ranges.join(',')
|
84
|
+
end
|
85
|
+
|
86
|
+
def pretty_subnet_name(subnet)
|
87
|
+
"#{subnet.name} (#{subnet.cidr})"
|
88
|
+
end
|
42
89
|
end
|
43
90
|
|
44
91
|
Cyoi::Cli::Address.register_address_cli("openstack", Cyoi::Cli::Addresses::AddressCliOpenstack)
|
@@ -2,17 +2,31 @@
|
|
2
2
|
|
3
3
|
module Cyoi; module Providers; module Clients; end; end; end
|
4
4
|
|
5
|
+
require "ipaddr"
|
5
6
|
require "cyoi/providers/clients/fog_provider_client"
|
6
7
|
require "cyoi/providers/constants/openstack_constants"
|
7
8
|
|
8
9
|
class Cyoi::Providers::Clients::OpenStackProviderClient < Cyoi::Providers::Clients::FogProviderClient
|
10
|
+
# @return [boolean] true if target OpenStack running Neutron networks
|
11
|
+
def networks?
|
12
|
+
fog_network
|
13
|
+
end
|
14
|
+
|
15
|
+
def subnets
|
16
|
+
fog_network.subnets
|
17
|
+
end
|
18
|
+
|
9
19
|
# @return [String] provisions a new public IP address in target region
|
10
|
-
# TODO nil if none available
|
11
20
|
def provision_public_ip_address(options={})
|
12
|
-
|
13
|
-
|
21
|
+
pool_name = options.delete("pool_name")
|
22
|
+
pool_name ||= begin
|
23
|
+
pool = fog_compute.addresses.get_address_pools.first
|
24
|
+
pool["name"]
|
25
|
+
end
|
26
|
+
address = fog_compute.addresses.create(:pool => pool_name)
|
14
27
|
address.ip
|
15
|
-
|
28
|
+
rescue NoMethodError
|
29
|
+
print "No Public IP Found"
|
16
30
|
end
|
17
31
|
|
18
32
|
def associate_ip_address_with_server(ip_address, server)
|
@@ -20,6 +34,36 @@ class Cyoi::Providers::Clients::OpenStackProviderClient < Cyoi::Providers::Clien
|
|
20
34
|
address.server = server
|
21
35
|
end
|
22
36
|
|
37
|
+
# @return [Array] of IPs that are not allocated to a server
|
38
|
+
# Defaults to the first address pool unless
|
39
|
+
# "pool_name" is provided in options
|
40
|
+
def unallocated_floating_ip_addresses(options={})
|
41
|
+
pool_name = options.delete("pool_name")
|
42
|
+
pool_name ||= begin
|
43
|
+
pool = fog_compute.addresses.get_address_pools.first
|
44
|
+
pool["name"]
|
45
|
+
end
|
46
|
+
fog_compute.addresses.
|
47
|
+
select { |a| a.pool == pool_name && a.instance_id.nil? }.
|
48
|
+
map(&:ip)
|
49
|
+
end
|
50
|
+
|
51
|
+
# @return [String] IP that is available for a new VM to use
|
52
|
+
# allocation_pools look like:
|
53
|
+
# "allocation_pools" => [{"start"=>"192.168.101.2", "end"=>"192.168.101.254"}]
|
54
|
+
def next_available_ip_in_subnet(subnet)
|
55
|
+
ip = IPAddr.new(subnet.allocation_pools.first["start"])
|
56
|
+
skip_ips = ip_addresses_assigned_to_servers
|
57
|
+
while skip_ips.include?(ip.to_s)
|
58
|
+
ip = ip.succ
|
59
|
+
end
|
60
|
+
ip.to_s
|
61
|
+
end
|
62
|
+
|
63
|
+
def ip_addresses_assigned_to_servers
|
64
|
+
fog_compute.servers.map {|s| s.addresses}.map {|address_hash| address_hash.map {|name, addrs| addrs}}.flatten.map {|addr| addr["addr"]}
|
65
|
+
end
|
66
|
+
|
23
67
|
# Hook method for FogProviderClient#create_security_group
|
24
68
|
def ip_permissions(sg)
|
25
69
|
sg.rules
|
@@ -59,17 +103,27 @@ class Cyoi::Providers::Clients::OpenStackProviderClient < Cyoi::Providers::Clien
|
|
59
103
|
raise "not implemented yet"
|
60
104
|
end
|
61
105
|
|
62
|
-
|
63
|
-
# Uses +attributes+ which normally originates from +settings.provider+
|
64
|
-
def setup_fog_connection
|
106
|
+
def configuration
|
65
107
|
configuration = Fog.symbolize_credentials(attributes.credentials)
|
66
108
|
configuration[:provider] = "OpenStack"
|
67
109
|
if attributes.credentials.openstack_region && attributes.credentials.openstack_region.empty?
|
68
110
|
configuration.delete(:openstack_region)
|
69
111
|
end
|
112
|
+
configuration
|
113
|
+
end
|
114
|
+
|
115
|
+
# Construct a Fog::Compute object
|
116
|
+
# Uses +attributes+ which normally originates from +settings.provider+
|
117
|
+
def setup_fog_connection
|
70
118
|
@fog_compute = Fog::Compute.new(configuration)
|
71
119
|
end
|
72
120
|
|
121
|
+
def fog_network
|
122
|
+
@fog_network ||= Fog::Network.new(configuration)
|
123
|
+
rescue Fog::Errors::NotFound
|
124
|
+
nil
|
125
|
+
end
|
126
|
+
|
73
127
|
def openstack_constants
|
74
128
|
Cyoi::Providers::Constants::OpenStackConstants
|
75
129
|
end
|
data/lib/cyoi/version.rb
CHANGED
@@ -0,0 +1,110 @@
|
|
1
|
+
require "fog"
|
2
|
+
require "fog/openstack"
|
3
|
+
require 'fog/openstack/models/network/subnets'
|
4
|
+
require "cyoi/providers"
|
5
|
+
|
6
|
+
describe "cyoi address openstack" do
|
7
|
+
before { Fog.mock!; Fog::Mock.reset }
|
8
|
+
let(:provider_attributes) do
|
9
|
+
{
|
10
|
+
"name" => "openstack",
|
11
|
+
"credentials" => {
|
12
|
+
"openstack_username" => "USERNAME",
|
13
|
+
"openstack_api_key" => "PASSWORD",
|
14
|
+
"openstack_tenant" => "TENANT",
|
15
|
+
"openstack_auth_url" => "http://someurl.com/v2/tokens",
|
16
|
+
"openstack_region" => "REGION"
|
17
|
+
}
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:fog_compute) { instance_double("Fog::Compute::OpenStack::Real") }
|
22
|
+
let(:fog_network_const) { class_double("Fog::Network").as_stubbed_const(:transfer_nested_constants => [:OpenStack]) }
|
23
|
+
let(:fog_network) { instance_double("Fog::Network::OpenStack::Real") }
|
24
|
+
let(:addresses) { instance_double("Fog::Compute::OpenStack::Addresses") }
|
25
|
+
let(:address) { instance_double("Fog::Compute::OpenStack::Address", ip: '1.2.3.4') }
|
26
|
+
let(:unallocated_address) { instance_double("Fog::Compute::OpenStack::Address", ip: '1.2.3.4', instance_id: nil, pool: 'INTERNET') }
|
27
|
+
let(:allocated_address) { instance_double("Fog::Compute::OpenStack::Address", ip: '1.2.3.4', instance_id: 'XXX', pool: 'INTERNET') }
|
28
|
+
let(:subnets) { instance_double("Fog::Network::OpenStack::Subnets") }
|
29
|
+
let(:networks) {}
|
30
|
+
|
31
|
+
subject { Cyoi::Providers.provider_client(provider_attributes) }
|
32
|
+
|
33
|
+
it "is an OpenStack provider" do
|
34
|
+
expect(subject).to be_instance_of(Cyoi::Providers::Clients::OpenStackProviderClient)
|
35
|
+
end
|
36
|
+
|
37
|
+
context "provision_public_ip_address" do
|
38
|
+
it "defaults to pool: 'nova' for nova" do
|
39
|
+
expect(subject).to receive(:fog_compute).exactly(2).times.and_return(fog_compute)
|
40
|
+
expect(fog_compute).to receive(:addresses).exactly(2).times.and_return(addresses)
|
41
|
+
expect(addresses).to receive(:get_address_pools).and_return([{"name"=>"nova"}])
|
42
|
+
expect(addresses).to receive(:create).with(pool: "nova").and_return(address)
|
43
|
+
expect(subject.provision_public_ip_address).to eq('1.2.3.4')
|
44
|
+
end
|
45
|
+
|
46
|
+
it "specify a pool name" do
|
47
|
+
expect(subject).to receive(:fog_compute).and_return(fog_compute)
|
48
|
+
expect(fog_compute).to receive(:addresses).and_return(addresses)
|
49
|
+
expect(addresses).to receive(:create).with(pool: "INTERNET").and_return(address)
|
50
|
+
expect(subject.provision_public_ip_address("pool_name" => "INTERNET")).to eq('1.2.3.4')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
it "returns unallocated floating IPs for a pool" do
|
55
|
+
expect(subject).to receive(:fog_compute).and_return(fog_compute)
|
56
|
+
expect(fog_compute).to receive(:addresses).and_return([unallocated_address, allocated_address])
|
57
|
+
expect(subject.unallocated_floating_ip_addresses("pool_name" => "INTERNET")).to eq(['1.2.3.4'])
|
58
|
+
end
|
59
|
+
|
60
|
+
context "networks" do
|
61
|
+
it "has no networks" do
|
62
|
+
expect(subject).to receive(:fog_network).and_return(nil)
|
63
|
+
expect(subject.networks?).to be_nil
|
64
|
+
end
|
65
|
+
|
66
|
+
context "has networks" do
|
67
|
+
before do
|
68
|
+
end
|
69
|
+
|
70
|
+
it "for sure" do
|
71
|
+
expect(subject).to receive(:fog_network).and_return(fog_network)
|
72
|
+
expect(subject.networks?).to_not be_nil
|
73
|
+
end
|
74
|
+
|
75
|
+
it "available subnets" do
|
76
|
+
expect(subject).to receive(:fog_network).and_return(fog_network)
|
77
|
+
expect(fog_network).to receive(:subnets).and_return(subnets)
|
78
|
+
expect(subject.subnets).to eq(subnets)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
context 'next_available_ip_in_subnet' do
|
83
|
+
let(:subnet) { Fog::Network::OpenStack::Subnet.new(
|
84
|
+
"cidr" => "192.168.101.0/24",
|
85
|
+
"gateway_ip" => "192.168.101.1",
|
86
|
+
"allocation_pools" => [{"start"=>"192.168.101.2", "end"=>"192.168.101.254"}]
|
87
|
+
) }
|
88
|
+
it "returns next IP in allocation pools" do
|
89
|
+
expect(subject.next_available_ip_in_subnet(subnet)).to eq("192.168.101.2")
|
90
|
+
end
|
91
|
+
|
92
|
+
it "avoids IP addresses already allocated to other servers" do
|
93
|
+
expect(subject).to receive(:ip_addresses_assigned_to_servers).and_return(["192.168.101.2", "192.168.101.3"])
|
94
|
+
expect(subject.next_available_ip_in_subnet(subnet)).to eq("192.168.101.4")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context 'ip_addresses_assigned_to_servers' do
|
99
|
+
let(:addresses) do
|
100
|
+
{"Internet Access "=>[{"OS-EXT-IPS-MAC:mac_addr"=>"fa:16:3e:c0:4b:b3", "version"=>4, "addr"=>"192.168.101.2", "OS-EXT-IPS:type"=>"fixed"}, {"OS-EXT-IPS-MAC:mac_addr"=>"fa:16:3e:c0:4b:b3", "version"=>4, "addr"=>"174.128.50.11", "OS-EXT-IPS:type"=>"floating"}]}
|
101
|
+
end
|
102
|
+
let(:servers) { [instance_double("Fog::Compute::OpenStack::Server", addresses: addresses)] }
|
103
|
+
it "list of IPs" do
|
104
|
+
expect(subject).to receive(:fog_compute).and_return(fog_compute)
|
105
|
+
expect(fog_compute).to receive(:servers).and_return(servers)
|
106
|
+
expect(subject.ip_addresses_assigned_to_servers).to eq(["192.168.101.2", "174.128.50.11"])
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
metadata
CHANGED
@@ -1,111 +1,125 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cyoi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dr Nic Williams
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2014-02-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: fog
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- -
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
19
|
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: highline
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
|
-
- - ~>
|
31
|
+
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
33
|
version: '1.6'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
|
-
- - ~>
|
38
|
+
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '1.6'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: readwritesettings
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - ~>
|
45
|
+
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
47
|
version: '3.0'
|
48
48
|
type: :runtime
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - ~>
|
52
|
+
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '3.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: bundler
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- -
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
- !ruby/object:Gem::Dependency
|
70
70
|
name: rake
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
72
72
|
requirements:
|
73
|
-
- -
|
73
|
+
- - ">="
|
74
74
|
- !ruby/object:Gem::Version
|
75
75
|
version: '0'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
|
-
- -
|
80
|
+
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: rspec
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
86
86
|
requirements:
|
87
|
-
- -
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: rspec-fire
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
88
102
|
- !ruby/object:Gem::Version
|
89
103
|
version: '0'
|
90
104
|
type: :development
|
91
105
|
prerelease: false
|
92
106
|
version_requirements: !ruby/object:Gem::Requirement
|
93
107
|
requirements:
|
94
|
-
- -
|
108
|
+
- - ">="
|
95
109
|
- !ruby/object:Gem::Version
|
96
110
|
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: aruba
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
100
114
|
requirements:
|
101
|
-
- -
|
115
|
+
- - ">="
|
102
116
|
- !ruby/object:Gem::Version
|
103
117
|
version: '0'
|
104
118
|
type: :development
|
105
119
|
prerelease: false
|
106
120
|
version_requirements: !ruby/object:Gem::Requirement
|
107
121
|
requirements:
|
108
|
-
- -
|
122
|
+
- - ">="
|
109
123
|
- !ruby/object:Gem::Version
|
110
124
|
version: '0'
|
111
125
|
description: A library to ask an end-user to choose an infrastructure (AWS, OpenStack,
|
@@ -117,9 +131,9 @@ executables:
|
|
117
131
|
extensions: []
|
118
132
|
extra_rdoc_files: []
|
119
133
|
files:
|
120
|
-
- .gitignore
|
121
|
-
- .rspec
|
122
|
-
- .travis.yml
|
134
|
+
- ".gitignore"
|
135
|
+
- ".rspec"
|
136
|
+
- ".travis.yml"
|
123
137
|
- ChangeLog.md
|
124
138
|
- Gemfile
|
125
139
|
- Guardfile
|
@@ -172,11 +186,13 @@ files:
|
|
172
186
|
- spec/integration/cli/provider/provider_aws_spec.rb
|
173
187
|
- spec/integration/cli/provider/provider_openstack_spec.rb
|
174
188
|
- spec/spec_helper.rb
|
189
|
+
- spec/support/rspec-fire.rb
|
175
190
|
- spec/support/settings_helper.rb
|
176
191
|
- spec/support/stdout_capture.rb
|
177
192
|
- spec/unit/.gitkeep
|
178
193
|
- spec/unit/cli/image_spec.rb
|
179
194
|
- spec/unit/cli/key_pair_spec.rb
|
195
|
+
- spec/unit/providers/clients/openstack_provider_client_spec.rb
|
180
196
|
homepage: https://github.com/drnic/cyoi
|
181
197
|
licenses:
|
182
198
|
- MIT
|
@@ -187,17 +203,17 @@ require_paths:
|
|
187
203
|
- lib
|
188
204
|
required_ruby_version: !ruby/object:Gem::Requirement
|
189
205
|
requirements:
|
190
|
-
- -
|
206
|
+
- - ">="
|
191
207
|
- !ruby/object:Gem::Version
|
192
208
|
version: '0'
|
193
209
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
194
210
|
requirements:
|
195
|
-
- -
|
211
|
+
- - ">="
|
196
212
|
- !ruby/object:Gem::Version
|
197
213
|
version: '0'
|
198
214
|
requirements: []
|
199
215
|
rubyforge_project:
|
200
|
-
rubygems_version: 2.1
|
216
|
+
rubygems_version: 2.2.1
|
201
217
|
signing_key:
|
202
218
|
specification_version: 4
|
203
219
|
summary: A library to ask an end-user to choose an infrastructure (AWS, OpenStack,
|
@@ -217,8 +233,10 @@ test_files:
|
|
217
233
|
- spec/integration/cli/provider/provider_aws_spec.rb
|
218
234
|
- spec/integration/cli/provider/provider_openstack_spec.rb
|
219
235
|
- spec/spec_helper.rb
|
236
|
+
- spec/support/rspec-fire.rb
|
220
237
|
- spec/support/settings_helper.rb
|
221
238
|
- spec/support/stdout_capture.rb
|
222
239
|
- spec/unit/.gitkeep
|
223
240
|
- spec/unit/cli/image_spec.rb
|
224
241
|
- spec/unit/cli/key_pair_spec.rb
|
242
|
+
- spec/unit/providers/clients/openstack_provider_client_spec.rb
|