ohboshwillitfit 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 3a73b0603f734bf9b868daf32fb7e95e9de171dd
4
+ data.tar.gz: 44b62bc8889bb050b3539e690dd82dd9b34db8e4
5
+ SHA512:
6
+ metadata.gz: 9bd591dd66ba07790f6d91259de62ab4f3ee8f3319b957ee0705b722f5bf58c9a78611c296ee823d207da7ee4b9dbb99a59ad1fbf94f267ef84ed4819e0e0bbf
7
+ data.tar.gz: e6ac405fbf24ad26aa9bfceeaf81c765bd6c1e0999ce139c47e2dbacd95fc79345c0ca15592da6d8e6d9845a0df13337897f95c60f95a89933325a43a764bb11
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format progress
2
+ --color
3
+ --require spec_helper
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ohboshwillitfit.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Dr Nic Williams
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # Oh BOSH, Will It Fit?
2
+
3
+ Find out early if your target deployment will fit into the quota/available limits of your target OpenStack tenancy.
4
+
5
+ If the deployment fits, then you'll see something like:
6
+
7
+ ![fits](https://www.evernote.com/shard/s3/sh/ce1c2d81-0070-4702-aa84-c426b777429d/0dd99134d3abab7dabd9d4e6cba23349/deep/0/drnic@drnic----gems-ohboshwillitfit---zsh---204-51.png)
8
+
9
+ If the deployment won't fit, then you'll see:
10
+
11
+ ![wont-fit](https://www.evernote.com/shard/s3/sh/c72b4de3-5955-4c82-9248-d50a46bab36c/0ee172f27ee41311101b029bfa34e04e/deep/0/drnic@drnic----gems-ohboshwillitfit---zsh---204-51.png)
12
+
13
+ If the deployment has an invalid flavor/instance type:
14
+
15
+ ![bad-flavor](https://www.evernote.com/shard/s3/sh/6d4a3c49-c841-455e-ab4b-039baae6dbd3/c904e89a317e870dea78a84bbaa6e6ae/deep/0/drnic@drnic----gems-ohboshwillitfit---zsh---204-51.png)
16
+
17
+ ## Installation
18
+
19
+ This BOSH CLI plugin is distributed as a RubyGem:
20
+
21
+ ```
22
+ gem install ohboshwillitfit
23
+ ```
24
+
25
+ ## Usage
26
+
27
+ Currently, you must have your target OpenStack's credentials stored in a `~/.fog` file and reference the key within that file:
28
+
29
+ ```
30
+ bosh will it fit --fog-key default
31
+ ```
32
+
33
+ ## Contributing
34
+
35
+ 1. Fork it ( http://github.com/<my-github-username>/ohboshwillitfit/fork )
36
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
37
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
38
+ 4. Push to the branch (`git push origin my-new-feature`)
39
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,67 @@
1
+ require "ohboshwillitfit"
2
+
3
+ module Bosh::Cli::Command
4
+ class WillItFit < Base
5
+
6
+ usage "will it fit"
7
+ desc "check if this deployment will fit into OpenStack tenancy"
8
+ option "--fog-key default", "Look up credentials in ~/.fog"
9
+ def will_it_fit
10
+ deployment_required
11
+
12
+ if fog_key = options[:fog_key]
13
+ credentials = OhBoshWillItFit::FogCredentials.load_from_file(fog_key)
14
+ end
15
+ fog_compute = Fog::Compute.new({provider: 'OpenStack'}.merge(credentials))
16
+ limits = OhBoshWillItFit::Limits.new(fog_compute)
17
+ unless limits.limits_available?
18
+ say "Older OpenStacks like this do not provide current resources being used.".make_yellow
19
+ say "Can only display output based on quotas, rather than unused limits."
20
+ end
21
+
22
+ flavors = fog_compute.flavors
23
+ flavor_errors = false
24
+
25
+ resources = OhBoshWillItFit::Resource.from_file(deployment)
26
+ OhBoshWillItFit::Resource.map_flavors!(resources, flavors)
27
+
28
+ say ""
29
+ say "Flavours used:"
30
+ resources.each do |resource|
31
+ if resource.error
32
+ say " #{resource.instance_type}: #{resource.error}".make_red
33
+ flavor_errors = true
34
+ else
35
+ say " #{resource.instance_type}: #{resource.size} (ram: #{resource.ram} disk: #{resource.disk} cpus: #{resource.cpus})"
36
+ end
37
+ end
38
+
39
+ say ""
40
+ if flavor_errors
41
+ say "Available flavors:".make_yellow
42
+ flavors.sort {|f1, f2| f1.ram <=> f2.ram}.each do |flavor|
43
+ say " #{flavor.name}: ram: #{flavor.ram} disk: #{flavor.disk} cpus: #{flavor.vcpus}"
44
+ end
45
+ else
46
+ say "Resources used:"
47
+ resource_totals = OhBoshWillItFit::Resource.resource_totals(resources)
48
+ display_resource "ram", resource_totals["ram"], limits.ram_size_available
49
+ display_resource "disk", resource_totals["disk"]
50
+ display_resource "cpus", resource_totals["cpus"], limits.cores_available
51
+ end
52
+ rescue => e
53
+ err e.message
54
+ end
55
+
56
+ private
57
+ def display_resource(label, total, max_total=nil)
58
+ if max_total
59
+ message = " #{label}: #{total} / #{max_total}"
60
+ message = total <= max_total ? message.make_green : message.make_red
61
+ else
62
+ message = " #{label}: #{total}"
63
+ end
64
+ say message
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,10 @@
1
+ module OhBoshWillItFit
2
+ class FogCredentials
3
+ def self.load_from_file(fog_key, fog_file="~/.fog")
4
+ fog_file = File.expand_path(fog_file)
5
+ return nil unless File.exists?(fog_file)
6
+ credentials = YAML.load_file(fog_file)
7
+ credentials[fog_key.to_sym] || credentials[fog_key.to_s]
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,58 @@
1
+ module OhBoshWillItFit
2
+ class Limits
3
+ attr_reader :fog_compute
4
+
5
+ def initialize(fog_compute)
6
+ @fog_compute = fog_compute
7
+ end
8
+
9
+ def max_total_cores
10
+ absolute_limits["maxTotalCores"]
11
+ end
12
+
13
+ def max_total_instances
14
+ absolute_limits["maxTotalInstances"]
15
+ end
16
+
17
+ def max_total_ram_size
18
+ absolute_limits["maxTotalRAMSize"]
19
+ end
20
+
21
+ def total_cores_used
22
+ absolute_limits["totalCoresUsed"]
23
+ end
24
+
25
+ def total_instances_used
26
+ absolute_limits["totalInstancesUsed"]
27
+ end
28
+
29
+ def total_ram_size_used
30
+ absolute_limits["totalRAMUsed"]
31
+ end
32
+
33
+ def limits_available?
34
+ total_cores_used && total_instances_used && total_ram_size_used
35
+ end
36
+
37
+ def cores_available
38
+ max_total_cores - (total_cores_used || 0)
39
+ end
40
+
41
+ def instances_available
42
+ max_total_instances - (total_instances_used || 0)
43
+ end
44
+
45
+ def ram_size_available
46
+ max_total_ram_size - (total_ram_size_used || 0)
47
+ end
48
+
49
+ def limits
50
+ @limits ||= fog_compute.get_limits
51
+ end
52
+
53
+ def absolute_limits
54
+ limits.data[:body]["limits"]["absolute"]
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,60 @@
1
+ module OhBoshWillItFit
2
+ class Resource
3
+ attr_accessor :instance_type
4
+ attr_accessor :size
5
+
6
+ attr_accessor :ram, :total_ram
7
+ attr_accessor :disk, :total_disk
8
+ attr_accessor :cpus, :total_cpus
9
+
10
+ attr_accessor :error
11
+
12
+ def self.from_file(deployment_path)
13
+ resource_pools = YAML.load_file(deployment_path)["resource_pools"]
14
+ resource_pools.map do |pool|
15
+ resource = self.new
16
+ resource.size = pool["size"]
17
+ resource.instance_type = pool["cloud_properties"]["instance_type"]
18
+ resource
19
+ end
20
+ end
21
+
22
+ def self.map_flavors!(resources, flavors)
23
+ resources.each do |resource|
24
+ if flavor = resource.find_flavor(flavors)
25
+ resource.apply_flavor(flavor)
26
+ else
27
+ resource.error = "Not a valid flavor/instance_type"
28
+ end
29
+ end
30
+ end
31
+
32
+ def self.resource_totals(resources)
33
+ totals = { "ram" => 0, "disk" => 0, "cpus" => 0 }
34
+ resources.each do |resource|
35
+ totals["ram"] += resource.total_ram if resource.total_ram
36
+ totals["disk"] += resource.total_disk if resource.total_disk
37
+ totals["cpus"] += resource.total_cpus if resource.total_cpus
38
+ end
39
+ totals
40
+ end
41
+
42
+ def find_flavor(flavors)
43
+ flavors.find { |flavor| flavor.name == instance_type }
44
+ end
45
+
46
+ def apply_flavor(flavor)
47
+ self.ram = flavor.ram
48
+ self.disk = flavor.disk
49
+ self.cpus = flavor.vcpus
50
+ update_totals!
51
+ end
52
+
53
+ def update_totals!
54
+ self.total_ram = size * ram
55
+ self.total_disk = size * disk
56
+ self.total_cpus = size * cpus
57
+ end
58
+
59
+ end
60
+ end
@@ -0,0 +1,3 @@
1
+ module OhBoshWillItFit
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,6 @@
1
+ require "fog"
2
+
3
+ require "ohboshwillitfit/version"
4
+ require "ohboshwillitfit/limits"
5
+ require "ohboshwillitfit/fog_credentials"
6
+ require "ohboshwillitfit/resource"
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ohboshwillitfit/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ohboshwillitfit"
8
+ spec.version = OhBoshWillItFit::VERSION
9
+ spec.authors = ["Dr Nic Williams"]
10
+ spec.email = ["drnicwilliams@gmail.com"]
11
+ spec.summary = %q{Will this OpenStack BOSH deployment fit or not? If not, fail fast.}
12
+ spec.description = <<-EOS
13
+ Lives have been wasted waiting for a BOSH deployment to run only to find that you
14
+ don't have a quota large enough. Not enough instances, CPU, RAM, disk or volumes. OMG.
15
+ Run this BOSH CLI plugin first to find out if it will fit. Fail fast.
16
+ EOS
17
+ spec.homepage = ""
18
+ spec.license = "MIT"
19
+
20
+ spec.files = `git ls-files -z`.split("\x0")
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.add_dependency "fog", "~> 1.0"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.5"
28
+ spec.add_development_dependency "rake"
29
+ spec.add_development_dependency "rspec-fire"
30
+ end
@@ -0,0 +1,6 @@
1
+ name: small
2
+ resource_pools:
3
+ - name: small
4
+ size: 2
5
+ cloud_properties:
6
+ instance_type: m1.small
@@ -0,0 +1,6 @@
1
+ name: wontfit
2
+ resource_pools:
3
+ - name: xlarge
4
+ size: 50
5
+ cloud_properties:
6
+ instance_type: m1.xlarge
@@ -0,0 +1,68 @@
1
+ {
2
+ "limits": {
3
+ "rate": [
4
+ {
5
+ "regex": ".*",
6
+ "limit": [
7
+ {
8
+ "next-available": "2014-03-17T19:30:42Z",
9
+ "unit": "MINUTE",
10
+ "verb": "POST",
11
+ "remaining": 9,
12
+ "value": 10
13
+ },
14
+ {
15
+ "next-available": "2014-03-20T00:56:41Z",
16
+ "unit": "MINUTE",
17
+ "verb": "PUT",
18
+ "remaining": 10,
19
+ "value": 10
20
+ },
21
+ {
22
+ "next-available": "2014-03-18T03:47:22Z",
23
+ "unit": "MINUTE",
24
+ "verb": "DELETE",
25
+ "remaining": 99,
26
+ "value": 100
27
+ }
28
+ ],
29
+ "uri": "*"
30
+ },
31
+ {
32
+ "regex": "^/servers",
33
+ "limit": [
34
+ {
35
+ "next-available": "2014-03-20T00:56:41Z",
36
+ "unit": "DAY",
37
+ "verb": "POST",
38
+ "remaining": 50,
39
+ "value": 50
40
+ }
41
+ ],
42
+ "uri": "*/servers"
43
+ },
44
+ {
45
+ "regex": ".*changes-since.*",
46
+ "limit": [
47
+ {
48
+ "next-available": "2014-03-20T00:56:41Z",
49
+ "unit": "MINUTE",
50
+ "verb": "GET",
51
+ "remaining": 3,
52
+ "value": 3
53
+ }
54
+ ],
55
+ "uri": "*changes-since*"
56
+ }
57
+ ],
58
+ "absolute": {
59
+ "maxServerMeta": 128,
60
+ "maxPersonality": 5,
61
+ "maxImageMeta": 128,
62
+ "maxPersonalitySize": 10240,
63
+ "maxTotalCores": 1000,
64
+ "maxTotalInstances": 100,
65
+ "maxTotalRAMSize": 1966080
66
+ }
67
+ }
68
+ }
@@ -0,0 +1,26 @@
1
+ {
2
+ "limits": {
3
+ "rate": [
4
+
5
+ ],
6
+ "absolute": {
7
+ "maxServerMeta": 128,
8
+ "maxPersonality": 5,
9
+ "maxImageMeta": 128,
10
+ "maxPersonalitySize": 10240,
11
+ "maxSecurityGroupRules": 20,
12
+ "maxTotalKeypairs": 100,
13
+ "maxSecurityGroups": 10,
14
+ "maxTotalCores": 50,
15
+ "maxTotalFloatingIps": 10,
16
+ "maxTotalInstances": 40,
17
+ "maxTotalRAMSize": 204800,
18
+
19
+ "totalSecurityGroupsUsed": 0,
20
+ "totalRAMUsed": 169472,
21
+ "totalInstancesUsed": 24,
22
+ "totalFloatingIpsUsed": 0,
23
+ "totalCoresUsed": 43
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,21 @@
1
+ describe OhBoshWillItFit::FogCredentials do
2
+ it "load_from_file for valid key" do
3
+ setup_fog_with_various_accounts_setup
4
+ expected = {
5
+ openstack_username: "USERNAME",
6
+ openstack_api_key: "PASSWORD",
7
+ openstack_tenant: "TENANT",
8
+ openstack_auth_url: "URL"
9
+ }
10
+ expect(OhBoshWillItFit::FogCredentials.load_from_file("default")).to eq(expected)
11
+ end
12
+
13
+ it "load_from_file for unknown key" do
14
+ setup_fog_with_various_accounts_setup
15
+ expect(OhBoshWillItFit::FogCredentials.load_from_file("xxx")).to be_nil
16
+ end
17
+
18
+ it ".fog doesn't exist" do
19
+ expect(OhBoshWillItFit::FogCredentials.load_from_file("default")).to be_nil
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ require "json"
2
+
3
+ describe OhBoshWillItFit::Limits do
4
+ context "fog_limits - no_totals" do
5
+ let(:fog_limits) { JSON.parse(File.read(spec_asset("fog_limits_no_totals.json"))) }
6
+ let(:get_limits) { instance_double("Excon::Response", data: { body: fog_limits} ) }
7
+ let(:fog_compute) { instance_double("Fog::Compute::OpenStack::Real", get_limits: get_limits) }
8
+ subject { OhBoshWillItFit::Limits.new(fog_compute) }
9
+ it {
10
+ expect(subject.max_total_cores).to eq(1000)
11
+ }
12
+ it {
13
+ expect(subject.max_total_instances).to eq(100)
14
+ }
15
+ it {
16
+ expect(subject.max_total_ram_size).to eq(1966080)
17
+ }
18
+ it {
19
+ expect(subject.total_cores_used).to eq(nil)
20
+ }
21
+ it {
22
+ expect(subject.total_instances_used).to eq(nil)
23
+ }
24
+ it {
25
+ expect(subject.total_ram_size_used).to eq(nil)
26
+ }
27
+
28
+ it {
29
+ expect(subject.limits_available?).to be_false
30
+ }
31
+
32
+ it {
33
+ expect(subject.cores_available).to eq(1000)
34
+ }
35
+ it {
36
+ expect(subject.instances_available).to eq(100)
37
+ }
38
+ it {
39
+ expect(subject.ram_size_available).to eq(1966080)
40
+ }
41
+ end
42
+
43
+ context "fog_limits - totals" do
44
+ let(:fog_limits) { JSON.parse(File.read(spec_asset("fog_limits_totals.json"))) }
45
+ let(:get_limits) { instance_double("Excon::Response", data: { body: fog_limits} ) }
46
+ let(:fog_compute) { instance_double("Fog::Compute::OpenStack::Real", get_limits: get_limits) }
47
+ subject { OhBoshWillItFit::Limits.new(fog_compute) }
48
+ it {
49
+ expect(subject.max_total_cores).to eq(50)
50
+ }
51
+ it {
52
+ expect(subject.max_total_instances).to eq(40)
53
+ }
54
+ it {
55
+ expect(subject.max_total_ram_size).to eq(204800)
56
+ }
57
+ it {
58
+ expect(subject.total_cores_used).to eq(43)
59
+ }
60
+ it {
61
+ expect(subject.total_instances_used).to eq(24)
62
+ }
63
+ it {
64
+ expect(subject.total_ram_size_used).to eq(169472)
65
+ }
66
+
67
+ it {
68
+ expect(subject.limits_available?).to be_true
69
+ }
70
+
71
+ it {
72
+ expect(subject.cores_available).to eq(50-43)
73
+ }
74
+ it {
75
+ expect(subject.instances_available).to eq(40-24)
76
+ }
77
+ it {
78
+ expect(subject.ram_size_available).to eq(204800-169472)
79
+ }
80
+ end
81
+
82
+ end
@@ -0,0 +1,59 @@
1
+ require "fog/openstack/models/compute/flavor"
2
+
3
+ describe OhBoshWillItFit::Resource do
4
+ let(:flavors) do
5
+ [
6
+ instance_double("Fog::Compute::OpenStack::Flavor", name: "m1.small", ram: 2048, disk: 12, vcpus: 1),
7
+ instance_double("Fog::Compute::OpenStack::Flavor", name: "m1.xlarge", ram: 16384, disk: 80, vcpus: 8)
8
+ ]
9
+ end
10
+
11
+ context "small deployment that will fit" do
12
+ let(:deployment_file) { spec_asset("deployment-small.yml") }
13
+ subject { OhBoshWillItFit::Resource.from_file(deployment_file) }
14
+ it { expect(subject.size).to eq(1) }
15
+ it { expect(subject.first.instance_type).to eq("m1.small") }
16
+ it { expect(subject.first.size).to eq(2) }
17
+
18
+ context "with flavors" do
19
+ before do
20
+ OhBoshWillItFit::Resource.map_flavors!(subject, flavors)
21
+ end
22
+ it { expect(subject.first.ram).to eq(2048) }
23
+ it { expect(subject.first.total_ram).to eq(4096) }
24
+ it { expect(subject.first.disk).to eq(12) }
25
+ it { expect(subject.first.total_disk).to eq(24) }
26
+ it { expect(subject.first.cpus).to eq(1) }
27
+ it { expect(subject.first.total_cpus).to eq(2) }
28
+ it {
29
+ totals = OhBoshWillItFit::Resource.resource_totals(subject)
30
+ expect(totals).to eq({"ram" => 4096, "disk" => 24, "cpus" => 2})
31
+ }
32
+ end
33
+ end
34
+
35
+ context "small deployment that won't fit" do
36
+ let(:deployment_file) { spec_asset("deployment-wontfit.yml") }
37
+ subject { OhBoshWillItFit::Resource.from_file(deployment_file) }
38
+ it { expect(subject.size).to eq(1) }
39
+ it { expect(subject.first.instance_type).to eq("m1.xlarge") }
40
+ it { expect(subject.first.size).to eq(50) }
41
+
42
+ context "with flavors" do
43
+ before do
44
+ OhBoshWillItFit::Resource.map_flavors!(subject, flavors)
45
+ end
46
+ it { expect(subject.first.ram).to eq(16384) }
47
+ it { expect(subject.first.total_ram).to eq(50 * 16384) }
48
+ it { expect(subject.first.disk).to eq(80) }
49
+ it { expect(subject.first.total_disk).to eq(50 * 80) }
50
+ it { expect(subject.first.cpus).to eq(8) }
51
+ it { expect(subject.first.total_cpus).to eq(50 * 8) }
52
+ it {
53
+ totals = OhBoshWillItFit::Resource.resource_totals(subject)
54
+ expect(totals).to eq({"ram" => 50 * 16384, "disk" => 50 * 80, "cpus" => 50 * 8})
55
+ }
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,63 @@
1
+ # Copyright (c) 2012-2013 Stark & Wayne, LLC
2
+
3
+ ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", __FILE__)
4
+
5
+ require "rubygems"
6
+ require "bundler"
7
+ Bundler.setup(:default, :test)
8
+
9
+ $:.unshift(File.expand_path("../../lib", __FILE__))
10
+
11
+ require "rspec/core"
12
+ require "ohboshwillitfit"
13
+
14
+ # for the #sh helper
15
+ require "rake"
16
+ require "rake/file_utils"
17
+
18
+ # load all files in spec/support/* (but not lower down)
19
+ Dir[File.dirname(__FILE__) + '/support/*'].each do |path|
20
+ require path unless File.directory?(path)
21
+ end
22
+
23
+ def setup_fog_with_various_accounts_setup
24
+ File.open(File.expand_path("~/.fog"), "w") do |f|
25
+ f << {
26
+ default: {
27
+ openstack_username: "USERNAME",
28
+ openstack_api_key: "PASSWORD",
29
+ openstack_tenant: "TENANT",
30
+ openstack_auth_url: "URL"
31
+ },
32
+ }.to_yaml
33
+ end
34
+ end
35
+
36
+ def spec_asset(filename)
37
+ File.expand_path("../assets/#{filename}", __FILE__)
38
+ end
39
+
40
+ def setup_home_dir
41
+ home_dir = File.expand_path("../../tmp/home", __FILE__)
42
+ FileUtils.rm_rf(home_dir)
43
+ FileUtils.mkdir_p(home_dir)
44
+ ENV['HOME'] = home_dir
45
+ end
46
+
47
+ def setup_path
48
+ ENV['PATH'] = File.expand_path("../../bin", __FILE__) + ":" + ENV['PATH']
49
+ end
50
+ # returns the file path to a file
51
+ # in the fake $HOME folder
52
+ def home_file(*path)
53
+ File.join(ENV['HOME'], *path)
54
+ end
55
+
56
+ RSpec.configure do |c|
57
+ c.before do
58
+ setup_home_dir
59
+ setup_path
60
+ end
61
+
62
+ c.color_enabled = true
63
+ end
@@ -0,0 +1,9 @@
1
+ require 'rspec/fire'
2
+
3
+ RSpec.configure do |config|
4
+ config.include(RSpec::Fire)
5
+ end
6
+
7
+ RSpec::Fire.configure do |config|
8
+ config.verify_constant_names = true
9
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: ohboshwillitfit
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Dr Nic Williams
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-20 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: fog
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: bundler
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '1.5'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '1.5'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec-fire
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: |2
70
+ Lives have been wasted waiting for a BOSH deployment to run only to find that you
71
+ don't have a quota large enough. Not enough instances, CPU, RAM, disk or volumes. OMG.
72
+ Run this BOSH CLI plugin first to find out if it will fit. Fail fast.
73
+ email:
74
+ - drnicwilliams@gmail.com
75
+ executables: []
76
+ extensions: []
77
+ extra_rdoc_files: []
78
+ files:
79
+ - ".gitignore"
80
+ - ".rspec"
81
+ - Gemfile
82
+ - LICENSE.txt
83
+ - README.md
84
+ - Rakefile
85
+ - lib/bosh/cli/commands/will_it_fit.rb
86
+ - lib/ohboshwillitfit.rb
87
+ - lib/ohboshwillitfit/fog_credentials.rb
88
+ - lib/ohboshwillitfit/limits.rb
89
+ - lib/ohboshwillitfit/resource.rb
90
+ - lib/ohboshwillitfit/version.rb
91
+ - ohboshwillitfit.gemspec
92
+ - spec/assets/deployment-small.yml
93
+ - spec/assets/deployment-wontfit.yml
94
+ - spec/assets/fog_limits_no_totals.json
95
+ - spec/assets/fog_limits_totals.json
96
+ - spec/fog_credentials_spec.rb
97
+ - spec/limits_spec.rb
98
+ - spec/resource_spec.rb
99
+ - spec/spec_helper.rb
100
+ - spec/support/rspec-fire.rb
101
+ homepage: ''
102
+ licenses:
103
+ - MIT
104
+ metadata: {}
105
+ post_install_message:
106
+ rdoc_options: []
107
+ require_paths:
108
+ - lib
109
+ required_ruby_version: !ruby/object:Gem::Requirement
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ requirements: []
120
+ rubyforge_project:
121
+ rubygems_version: 2.2.1
122
+ signing_key:
123
+ specification_version: 4
124
+ summary: Will this OpenStack BOSH deployment fit or not? If not, fail fast.
125
+ test_files:
126
+ - spec/assets/deployment-small.yml
127
+ - spec/assets/deployment-wontfit.yml
128
+ - spec/assets/fog_limits_no_totals.json
129
+ - spec/assets/fog_limits_totals.json
130
+ - spec/fog_credentials_spec.rb
131
+ - spec/limits_spec.rb
132
+ - spec/resource_spec.rb
133
+ - spec/spec_helper.rb
134
+ - spec/support/rspec-fire.rb