ohboshwillitfit 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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