joyent-cloud-pricing 1.0.6 → 1.0.7

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9b380b01b5301c09ce4946aed2d0d55879ea978a
4
- data.tar.gz: 1eddbc97807b98e7e7ec1144226e47e61fef5414
3
+ metadata.gz: 6830b1d71aec26c98b251688edacd2a40448eac1
4
+ data.tar.gz: bfdeb0a822f1f8f6b15122402c4dbc491a061349
5
5
  SHA512:
6
- metadata.gz: bba5bd633fa5e1d02037487c549d130bb43cf8b473c33544e623aea153e3a71fdc17ec8f0a395c31fe2efcd79fc4f5e3ee6bb3db29dceba3169120d23c5f2c62
7
- data.tar.gz: 3ab4786f322d28b6077395eb2042a51ae079d78b88230ba5069745f0b43fe2314b49cda55208e0b58067c18cca224096201b1b05365d019c483d5f48705e8fd1
6
+ metadata.gz: 8c8bf089f0fe1f5e7361061ab4dcad2bc10845f64b2bdd92c40a20391910b59bdb8cc47540a5318eb9b656a0aef4552230c04bab1a6c8af5db9a3b40da0be958
7
+ data.tar.gz: cca584aaaecb758178cf1212a04400e1e8856a1c7c81b04a6b4e7ee6d6910ee137b2cc28da2f9d6e4f638e89fc6fc3f9242d67a4bb7e08a01f841236776267a8
data/.coveralls.yml ADDED
@@ -0,0 +1 @@
1
+ service_name: travis-ci
data/.gitignore CHANGED
@@ -16,3 +16,4 @@ test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
18
  .idea/**
19
+ **.DS_Store
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  [![Gem Version](https://badge.fury.io/rb/joyent-cloud-pricing.png)](http://badge.fury.io/rb/joyent-cloud-pricing)
2
2
  [![Build status](https://secure.travis-ci.org/kigster/joyent-cloud-pricing.png)](http://travis-ci.org/kigster/joyent-cloud-pricing)
3
3
  [![Code Climate](https://codeclimate.com/github/kigster/joyent-cloud-pricing.png)](https://codeclimate.com/github/kigster/joyent-cloud-pricing)
4
+ [![Coverage Status](https://coveralls.io/repos/kigster/joyent-cloud-pricing/badge.png?branch=master)](https://coveralls.io/r/kigster/joyent-cloud-pricing?branch=master)
4
5
 
5
6
  # Joyent Cloud Pricing
6
7
 
@@ -64,14 +65,19 @@ rake joyent:pricing:update
64
65
  Full price is stored in the configuration instance.
65
66
 
66
67
  ```ruby
67
- Joyent::Cloud::Pricing::Configuration.instance["g3-standard-48-smartos"]
68
- # => 1.536
68
+ c = Joyent::Cloud::Pricing::Configuration.instance
69
+ f = c.flavor "g3-highmemory-34.25-kvm"
70
+ f.to_h
71
+ # => {:name=>"g3-highmemory-34.25-kvm", :os=>"Linux",
72
+ # :cost=>0.817, :cpus=>4.0, :disk=>843, :ram=>34.25}
73
+ f.name
74
+ # => "g3-highmemory-34.25-kvm"
69
75
  ```
70
76
 
71
77
  ## Analysis of Commit Pricing
72
78
 
73
- _DISCLAIMER_: please note that prices specified in this sample commit configuration
74
- are completely arbitrary and have no relationship to any actual discounts issued by Joyent, Inc.
79
+ > DISCLAIMER: please note that prices specified in this sample commit configuration
80
+ > are completely arbitrary and have no relationship to any actual discounts issued by Joyent, Inc.
75
81
 
76
82
  Reserve pricing is meant to be defined by a YAML file, outside of the gem folder,
77
83
  somewhere on the file system. File looks like this.
@@ -116,7 +122,7 @@ flavors = %w(
116
122
  commit = Joyent::Cloud::Pricing::Commit.from_yaml 'my_company/config/joyent-commit-pricing.yml'
117
123
  analyzer = Joyent::Cloud::Pricing::Analyzer.new(commit, flavors)
118
124
 
119
- analyzer.monthly_overages_price # => monthly $$ for instances in excess of reserve
125
+ analyzer.monthly_overages_price # => monthly $$ for instances in excess of reserve
120
126
  analyzer.over_reserved_zone_list # => list of zones in reserve, but not in reality
121
127
  ```
122
128
 
@@ -126,15 +132,11 @@ This module is used by ```knife joyent server price``` plugin to calculate prici
126
132
  reserve discounts.
127
133
 
128
134
  ```ruby
129
- current_zone_list = %w(
130
- g3-highcpu-8-smartos
131
- g3-highcpu-8-smartos
132
- # ....
133
- )
135
+ current_zone_list = %w(g3-highcpu-8-smartos g3-highcpu-8-smartos )
134
136
 
135
- reporter = Joyent::Cloud::Pricing::Reporter.new(
136
- 'config/reserve-commit.yml',
137
- current_zone_list)
137
+ reporter = Joyent::Cloud::Pricing::Reporter.new(
138
+ 'config/reserve-commit.yml',
139
+ current_zone_list)
138
140
 
139
141
  puts reporter.render
140
142
  ```
@@ -169,7 +171,7 @@ MONTHLY COSTS:
169
171
  YEARLY COSTS:
170
172
  On demand yearly $77,189.76
171
173
  Reserve prepay one time fee $98,600.00
172
- Reserve monthly fees $104,640.00
174
+ Reserve sum of all monthly fees $104,640.00
173
175
  ___________
174
176
  Total $280,429.76
175
177
 
@@ -179,6 +181,16 @@ YEARLY RESERVE SAVINGS:
179
181
  .................................................................
180
182
  ```
181
183
 
184
+ ## Usage with knife joyent
185
+
186
+ This gem is integrated with latest version of [knife-joyent](https://github.com/joyent/knife-joyent) gem.
187
+
188
+ Use it as follows:
189
+
190
+ ```
191
+ knife joyent server pricing -z -r config/my-reserve-config.yml
192
+ ```
193
+
182
194
  ## Contributing
183
195
 
184
196
  1. Fork it
@@ -189,9 +201,9 @@ YEARLY RESERVE SAVINGS:
189
201
 
190
202
  ## Disclaimer
191
203
 
192
- This gem is provided as a convenience tool in understanding and comparing cloud pricing. No warranties,
193
- explicit or implied, are made in relation to correctness or accuracy of the calculations provided by this
194
- library. Use at your own risk.
204
+ > This gem is provided as a convenience tool in understanding and comparing cloud pricing. No warranties,
205
+ > explicit or implied, are made in relation to correctness or accuracy of the calculations provided by this
206
+ > library. Use at your own risk.
195
207
 
196
208
  ## Author
197
209
 
@@ -24,6 +24,7 @@ Gem::Specification.new do |spec|
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.5'
26
26
  spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'coveralls'
27
28
 
28
29
  spec.add_development_dependency 'rspec'
29
30
  spec.add_development_dependency 'rspec-mocks'
@@ -24,6 +24,17 @@ module Joyent::Cloud::Pricing
24
24
  h
25
25
  end
26
26
 
27
+ # Zones with flavor that's not recognized, and therefore unknown
28
+ def unknown_zone_counts
29
+ h = {}
30
+ zone_counts.each_pair { |flavor, count| h[flavor] = count if pricing.flavor(flavor).nil? }
31
+ h
32
+ end
33
+
34
+ def have_unknown_zones?
35
+ unknown_zone_counts.size > 0
36
+ end
37
+
27
38
  # Non-discounted full price
28
39
  def monthly_full_price
29
40
  monthly_full_price_for(zone_counts)
@@ -91,7 +102,8 @@ module Joyent::Cloud::Pricing
91
102
  def count_props(operation)
92
103
  results = [ zone_counts, excess_zone_counts, commit.flavor_counts ].map do |list|
93
104
  count_for_all list do |flavor|
94
- pricing.flavor(flavor).send(operation)
105
+ f = pricing.flavor(flavor)
106
+ f.respond_to?(operation.to_sym) ? f.send(operation) : 0
95
107
  end
96
108
  end
97
109
  { total: results[0], unreserved: results[1], reserved: results[2] }
@@ -4,7 +4,7 @@ require_relative 'flavor'
4
4
 
5
5
  module Joyent::Cloud::Pricing
6
6
  class Configuration
7
- @@lock = Mutex.new # just in case
7
+ @@lock = Mutex.new
8
8
 
9
9
  class << self
10
10
  def instance(reload = false)
@@ -54,13 +54,7 @@ module Joyent::Cloud::Pricing
54
54
 
55
55
  def monthly(flavor)
56
56
  f = self.cost(flavor)
57
- if f.nil?
58
- STDERR.puts "WARNING: can't find flavor #{flavor}, assuming 0"
59
- 0
60
- else
61
- monthly_from_hourly f
62
- end
63
-
57
+ f.nil? ? 0 : monthly_from_hourly(f)
64
58
  end
65
59
 
66
60
  def save_yaml(filename = PRICING_FILENAME)
@@ -20,7 +20,7 @@ module Joyent::Cloud::Pricing
20
20
  end
21
21
 
22
22
  @zones_in_use = zones_in_use
23
- @analyzer = Joyent::Cloud::Pricing::Analyzer.new(@commit, @zones_in_use)
23
+ @analyzer = Joyent::Cloud::Pricing::Analyzer.new(@commit, @zones_in_use)
24
24
  @formatter = Joyent::Cloud::Pricing::Formatter.new(pricing.config)
25
25
  @print_zone_list = true
26
26
  end
@@ -44,7 +44,9 @@ module Joyent::Cloud::Pricing
44
44
  end
45
45
 
46
46
  def excess_zones
47
- zones = analyzer.excess_zone_counts.each_pair.map{|flavor, count| [ flavor, count, pricing.monthly(flavor) * count ]}.sort{|x,y| y[2] <=> x[2]}
47
+ zones = analyzer.excess_zone_counts.each_pair.
48
+ map{|flavor, count| [ flavor, count, pricing.monthly(flavor) * count ]}.
49
+ sort{|x,y| y[2] <=> x[2]}
48
50
  zones
49
51
  end
50
52
 
@@ -67,6 +69,15 @@ module Joyent::Cloud::Pricing
67
69
  PROPS_FORMAT= '%20d %20d %20d'
68
70
  REPORT_ASCII = <<ASCII
69
71
 
72
+ <%- if @r.analyzer.have_unknown_zones? -%>
73
+ <%= "WARNING!".red %>: flavor list has values which were not recognized, and
74
+ were excluded from calculations. Add them to legacy_prices.yml.
75
+
76
+ List of flavors with unknown properties:
77
+ <%= @r.analyzer.unknown_zone_counts.keys.map{|k| sprintf(" %20s", k) }.join("\n").red %>
78
+ <%= SEPARATOR %>
79
+
80
+ <%- end -%>
70
81
  ZONE COUNTS:
71
82
  Total # of zones <%= sprintf("%20d", @r.zones).cyan %>
72
83
  <%- if @r.reserve? -%>
@@ -100,7 +111,7 @@ YEARLY COSTS:
100
111
  <%- if @r.reserve? -%>
101
112
  On demand yearly <%= @f.format_price(@r.analyzer.yearly_overages_price, 20).yellow %>
102
113
  Reserve prepay one time fee <%= @f.format_price(@r.commit.upfront_price, 20).green %>
103
- Reserve monthly fees <%= @f.format_price(@r.commit.monthly_price * 12, 20).green %>
114
+ Reserve sum of all monthly fees <%= @f.format_price(@r.commit.monthly_price * 12, 20).green %>
104
115
  <%= "___________".cyan %>
105
116
  Total <%= @f.format_price(@r.analyzer.yearly_total, 20).cyan %>
106
117
  <%- else -%>
@@ -1,7 +1,7 @@
1
1
  module Joyent
2
2
  module Cloud
3
3
  module Pricing
4
- VERSION = '1.0.6'
4
+ VERSION = '1.0.7'
5
5
  end
6
6
  end
7
7
  end
@@ -2,41 +2,44 @@ require 'spec_helper'
2
2
 
3
3
  describe 'Joyent::Cloud::Pricing::Analyzer' do
4
4
 
5
- let(:flavors) { %w(
6
- g3-highcpu-16-smartos
7
- g3-highcpu-16-smartos
8
- g3-standard-30-smartos
9
- g3-highcpu-32-smartos-cc
10
- g3-highcpu-32-smartos-cc
11
- g3-highcpu-32-smartos-cc
12
- g3-highcpu-32-smartos-cc
13
- g3-highcpu-32-smartos-cc
14
- g3-highcpu-32-smartos-cc
15
- g3-highcpu-32-smartos-cc
16
- g3-highcpu-32-smartos-cc
17
- g3-highcpu-32-smartos-cc
18
- g3-highcpu-32-smartos-cc
19
- g3-highcpu-32-smartos-cc
20
- g3-highcpu-32-smartos-cc
21
- g3-highcpu-7-smartos
22
- g3-highcpu-7-smartos
23
- g3-highio-60.5-smartos
24
- g3-highio-60.5-smartos
25
- g3-highio-60.5-smartos
26
- g3-highio-60.5-smartos
27
- g3-highmemory-17.125-smartos
28
- g3-highmemory-17.125-smartos
29
- g3-highmemory-17.125-smartos
30
- g3-highmemory-17.125-smartos
31
- g3-highmemory-17.125-smartos
32
- g3-highmemory-17.125-smartos
33
- g3-highmemory-17.125-smartos
34
- g3-highmemory-17.125-smartos
35
- g3-highmemory-17.125-smartos
36
- g3-highmemory-17.125-smartos
37
- g3-highmemory-17.125-smartos
38
- g3-highmemory-17.125-smartos
39
- ) }
5
+ FLAVORS = %w(
6
+ g3-highcpu-16-smartos
7
+ g3-highcpu-16-smartos
8
+ g3-standard-30-smartos
9
+ g3-highcpu-32-smartos-cc
10
+ g3-highcpu-32-smartos-cc
11
+ g3-highcpu-32-smartos-cc
12
+ g3-highcpu-32-smartos-cc
13
+ g3-highcpu-32-smartos-cc
14
+ g3-highcpu-32-smartos-cc
15
+ g3-highcpu-32-smartos-cc
16
+ g3-highcpu-32-smartos-cc
17
+ g3-highcpu-32-smartos-cc
18
+ g3-highcpu-32-smartos-cc
19
+ g3-highcpu-32-smartos-cc
20
+ g3-highcpu-32-smartos-cc
21
+ g3-highcpu-7-smartos
22
+ g3-highcpu-7-smartos
23
+ g3-highio-60.5-smartos
24
+ g3-highio-60.5-smartos
25
+ g3-highio-60.5-smartos
26
+ g3-highio-60.5-smartos
27
+ g3-highmemory-17.125-smartos
28
+ g3-highmemory-17.125-smartos
29
+ g3-highmemory-17.125-smartos
30
+ g3-highmemory-17.125-smartos
31
+ g3-highmemory-17.125-smartos
32
+ g3-highmemory-17.125-smartos
33
+ g3-highmemory-17.125-smartos
34
+ g3-highmemory-17.125-smartos
35
+ g3-highmemory-17.125-smartos
36
+ g3-highmemory-17.125-smartos
37
+ g3-highmemory-17.125-smartos
38
+ g3-highmemory-17.125-smartos
39
+ some-unknown-flavor
40
+ )
41
+
42
+ let(:flavors) { FLAVORS }
40
43
  let(:commit) { Joyent::Cloud::Pricing::Commit.from_yaml 'spec/fixtures/commit.yml' }
41
44
  let(:analyzer) { Joyent::Cloud::Pricing::Analyzer.new(commit, flavors) }
42
45
 
@@ -53,7 +56,8 @@ describe 'Joyent::Cloud::Pricing::Analyzer' do
53
56
  :'g3-highcpu-7-smartos' => 2,
54
57
  :'g3-highio-60.5-smartos' => 4,
55
58
  :'g3-highmemory-17.125-smartos' => 12,
56
- :'g3-standard-30-smartos' => 1
59
+ :'g3-standard-30-smartos' => 1,
60
+ :'some-unknown-flavor' => 1
57
61
  })
58
62
  end
59
63
 
@@ -73,7 +77,8 @@ describe 'Joyent::Cloud::Pricing::Analyzer' do
73
77
  {:'g3-highcpu-16-smartos' => 2,
74
78
  :'g3-highcpu-32-smartos-cc' => 2,
75
79
  :'g3-highcpu-7-smartos' => 2,
76
- :'g3-standard-30-smartos' => 1
80
+ :'g3-standard-30-smartos' => 1,
81
+ :'some-unknown-flavor' => 1
77
82
  })
78
83
  end
79
84
 
@@ -95,4 +100,11 @@ describe 'Joyent::Cloud::Pricing::Analyzer' do
95
100
  expect(analyzer.disk).to eql({total: 28655.0, unreserved: 5807.0, reserved: 24300.0})
96
101
  end
97
102
  end
103
+
104
+ context 'for unknown instances' do
105
+ it 'should return some-unknown-flavor' do
106
+ expect(analyzer.unknown_zone_counts).to eql({ :'some-unknown-flavor' => 1 })
107
+ end
108
+ end
109
+
98
110
  end
@@ -36,6 +36,8 @@ describe 'Joyent::Cloud::Pricing::Reporter' do
36
36
  g3-highmemory-17.125-smartos
37
37
  g3-highmemory-17.125-smartos
38
38
  g3-highmemory-17.125-smartos
39
+ some-fake-flavor-without-pricing
40
+ some-fake-flavor-again
39
41
  ) }
40
42
  let(:commit) { Joyent::Cloud::Pricing::Commit.from_yaml 'spec/fixtures/commit.yml' }
41
43
  let(:reporter) { Joyent::Cloud::Pricing::Reporter.new(commit, flavors) }
data/spec/spec_helper.rb CHANGED
@@ -3,6 +3,8 @@ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
3
3
  require 'rubygems'
4
4
  require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5
5
  require 'pricing'
6
+ require 'coveralls'
7
+ Coveralls.wear!
6
8
 
7
9
  # Dir['spec/support/**/*.rb'].each { |filename| require_relative "../#{filename}" }
8
10
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: joyent-cloud-pricing
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Konstantin Gredeskoul
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-30 00:00:00.000000000 Z
11
+ date: 2014-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: coveralls
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
69
83
  - !ruby/object:Gem::Dependency
70
84
  name: rspec
71
85
  requirement: !ruby/object:Gem::Requirement
@@ -102,6 +116,7 @@ executables: []
102
116
  extensions: []
103
117
  extra_rdoc_files: []
104
118
  files:
119
+ - ".coveralls.yml"
105
120
  - ".gitignore"
106
121
  - ".rspec"
107
122
  - ".travis.yml"