vault_client 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/helpers/http_helpers.rb +45 -0
- data/lib/models/account.rb +13 -0
- data/lib/models/acct_own.rb +31 -0
- data/lib/models/b_event.rb +27 -0
- data/lib/models/billable_unit.rb +5 -2
- data/lib/models/line_item.rb +2 -4
- data/lib/models/report.rb +51 -0
- data/lib/models/res_own.rb +31 -0
- data/lib/models/unit_group.rb +20 -21
- data/lib/presenters/base_presenter.rb +6 -3
- data/lib/presenters/line_item_presenter.rb +27 -45
- data/lib/presenters/report_presenter.rb +10 -4
- data/lib/presenters/unit_group_presenter.rb +21 -36
- data/lib/presenters/unit_presenter.rb +3 -3
- data/lib/services/line_item_builder.rb +1 -1
- data/lib/vault_client.rb +18 -74
- data/readme.md +190 -26
- data/test/models/b_event_test.rb +20 -0
- data/test/models/billable_unit_test.rb +8 -0
- data/test/models/line_item_test.rb +10 -0
- data/test/models/unit_group_test.rb +17 -0
- data/test/presenters/line_item_presenter_test.rb +36 -0
- data/test/presenters/report_presenter_test.rb +10 -4
- data/test/services/line_item_builder_test.rb +9 -5
- data/test/test_helper.rb +4 -6
- metadata +24 -20
- data/lib/billable_events_client.rb +0 -45
- data/lib/dto/billable_event.rb +0 -0
- data/lib/dto/usage_report.rb +0 -35
- data/lib/models/usage_report.rb +0 -21
- data/lib/resource_ownership_client.rb +0 -55
- data/lib/services/report_builder.rb +0 -15
- data/lib/usage_reports_client.rb +0 -28
- data/lib/vault_helper.rb +0 -15
- data/test/models/usage_report_test.rb +0 -38
- data/test/resource_ownership_client_test.rb +0 -42
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module VC
|
2
2
|
class UnitGroupPresenter < BasePresenter
|
3
3
|
|
4
4
|
attr_reader :unit_group
|
@@ -12,45 +12,33 @@ module VaultClient
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def unit_presenters
|
15
|
-
|
16
|
-
@unit_presenters
|
17
|
-
else
|
18
|
-
@unit_presenters = @unit_group.units.map {|u| UnitPresenter.new(u)}
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
def template
|
23
|
-
if @unit_group.dyno_type?
|
24
|
-
"line_item_types/dyno"
|
25
|
-
elsif @unit_group.add_on_type?
|
26
|
-
"line_item_types/add_on"
|
27
|
-
elsif @unit_group.additional_type?
|
28
|
-
"line_item_types/additional"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def detail_template
|
33
|
-
if @unit_group.run_type?
|
34
|
-
"unit_group_types/flat"
|
35
|
-
elsif @unit_group.dyno_type?
|
36
|
-
"unit_group_types/metered"
|
37
|
-
else
|
38
|
-
"unit_group_types/brief"
|
39
|
-
end
|
15
|
+
@unit_presenters ||= @unit_group.units.map {|u| UnitPresenter.new(u)}
|
40
16
|
end
|
41
17
|
|
42
18
|
def daily_report_url
|
43
|
-
#TODO remove stub
|
19
|
+
#TODO remove chart stub
|
44
20
|
#payments_uri("/billable_units/daily")
|
45
21
|
"/billable_units/daily"
|
46
22
|
end
|
47
23
|
|
48
24
|
def compacted_reports
|
49
|
-
#TODO remove stub
|
25
|
+
#TODO remove chart stub
|
50
26
|
#BillableUnitReporter.compacted(@unit_group.units)
|
51
27
|
[]
|
52
28
|
end
|
53
29
|
|
30
|
+
def total
|
31
|
+
money(@unit_group.total)
|
32
|
+
end
|
33
|
+
|
34
|
+
def qty
|
35
|
+
trunc_hours(@unit_group.qty)
|
36
|
+
end
|
37
|
+
|
38
|
+
def rate
|
39
|
+
@unit_group.rate
|
40
|
+
end
|
41
|
+
|
54
42
|
def name
|
55
43
|
@unit_group.name
|
56
44
|
end
|
@@ -59,20 +47,17 @@ module VaultClient
|
|
59
47
|
@unit_group.description
|
60
48
|
end
|
61
49
|
|
62
|
-
def
|
63
|
-
|
50
|
+
def product_name
|
51
|
+
@unit_group.product_name
|
64
52
|
end
|
65
53
|
|
66
|
-
def
|
54
|
+
def product_group
|
55
|
+
@unit_group.product_group
|
67
56
|
end
|
68
57
|
|
69
58
|
def unit_of_measure
|
70
|
-
|
71
|
-
|
72
|
-
def total
|
73
|
-
money(@unit_group.total)
|
59
|
+
@unit_group.rate_period
|
74
60
|
end
|
75
61
|
|
76
62
|
end
|
77
63
|
end
|
78
|
-
|
@@ -1,4 +1,4 @@
|
|
1
|
-
module
|
1
|
+
module VC
|
2
2
|
class UnitPresenter < BasePresenter
|
3
3
|
|
4
4
|
def initialize(unit)
|
@@ -6,7 +6,7 @@ module VaultClient
|
|
6
6
|
end
|
7
7
|
|
8
8
|
def total
|
9
|
-
money(@unit.
|
9
|
+
money(@unit.total)
|
10
10
|
end
|
11
11
|
|
12
12
|
def rate
|
@@ -26,7 +26,7 @@ module VaultClient
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def description
|
29
|
-
@unit.
|
29
|
+
@unit.product_name
|
30
30
|
end
|
31
31
|
|
32
32
|
end
|
data/lib/vault_client.rb
CHANGED
@@ -1,88 +1,32 @@
|
|
1
|
-
require 'rest-client'
|
2
1
|
require 'yajl'
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
require 'billable_events_client'
|
6
|
-
require 'usage_reports_client'
|
7
|
-
|
8
|
-
module VaultClient
|
9
|
-
|
10
|
-
AuthenticationError = Class.new(Exception)
|
11
|
-
AuthorizationError = Class.new(Exception)
|
12
|
-
ServiceDownError = Class.new(Exception)
|
13
|
-
UnexpectedError = Class.new(Exception)
|
14
|
-
SymanticError = Class.new(Exception)
|
15
|
-
|
16
|
-
attr_accessor :url
|
2
|
+
require 'rest-client'
|
3
|
+
require 'helpers/http_helpers'
|
17
4
|
|
5
|
+
module VC
|
18
6
|
extend self
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
def billable_events(action, args={})
|
29
|
-
if ENV["VAULT_CLIENT_UNSAFE"] == "true"
|
30
|
-
make_unsafe_request! {BillableEventsClient.make_request(action, args)}
|
31
|
-
else
|
32
|
-
make_http_request {BillableEventsClient.make_request(action, args)}
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
def make_unsafe_request!
|
37
|
-
begin
|
38
|
-
resp = yield
|
39
|
-
JSON.parse(resp.body)
|
40
|
-
rescue RestClient => e
|
41
|
-
return e.inspect
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
def make_http_request(&block)
|
46
|
-
block.call() do |resp, req, res|
|
47
|
-
response_body = JSON.parse(resp.body)
|
48
|
-
case resp.code
|
49
|
-
when 200, 201
|
50
|
-
response_body
|
51
|
-
when 400, 401,
|
52
|
-
raise(AuthenticationError, response_body)
|
53
|
-
when 403
|
54
|
-
raise(AuthorizationError, response_body)
|
55
|
-
when 404
|
56
|
-
raise(NotFound, response_body)
|
57
|
-
when 422
|
58
|
-
raise(SymanticError, response_body)
|
59
|
-
when 500
|
60
|
-
raise(UnexpectedError)
|
61
|
-
when 503
|
62
|
-
raise(ServiceDownError)
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def url
|
68
|
-
@url || ENV["VAULT_URL"]
|
69
|
-
end
|
70
|
-
|
7
|
+
extend HttpHelpers
|
8
|
+
|
9
|
+
VCException = Class.new(Exception)
|
10
|
+
AuthenticationError = Class.new(VCException)
|
11
|
+
AuthorizationError = Class.new(VCException)
|
12
|
+
ServiceDownError = Class.new(VCException)
|
13
|
+
UnexpectedError = Class.new(VCException)
|
14
|
+
SymanticError = Class.new(VCException)
|
71
15
|
end
|
72
16
|
|
73
|
-
$:.unshift("lib")
|
74
17
|
|
75
|
-
require 'models/
|
18
|
+
require 'models/account'
|
76
19
|
require 'models/billable_unit'
|
20
|
+
require 'models/report'
|
77
21
|
require 'models/unit_group'
|
78
22
|
require 'models/line_item'
|
23
|
+
require 'models/b_event'
|
24
|
+
require 'models/res_own'
|
79
25
|
|
80
26
|
require 'services/line_item_builder'
|
81
|
-
require 'services/report_builder'
|
82
|
-
|
83
|
-
require 'dto/usage_report'
|
84
27
|
|
85
28
|
require 'presenters/base_presenter'
|
86
|
-
require 'presenters/report_presenter'
|
87
|
-
require 'presenters/line_item_presenter'
|
88
29
|
require 'presenters/unit_group_presenter'
|
30
|
+
require 'presenters/unit_presenter'
|
31
|
+
require 'presenters/line_item_presenter'
|
32
|
+
require 'presenters/report_presenter'
|
data/readme.md
CHANGED
@@ -3,17 +3,15 @@
|
|
3
3
|
## Purpose
|
4
4
|
|
5
5
|
This gem wraps the APIs defined [here](https://github.com/heroku/shushu/tree/master/doc).
|
6
|
+
The vault_client also provides a set of objects that help with the presentation
|
7
|
+
of an invoice.
|
6
8
|
|
7
|
-
##
|
8
|
-
|
9
|
-
### Setup
|
9
|
+
## Setup
|
10
10
|
|
11
11
|
```bash
|
12
12
|
$ gem install vault_client
|
13
13
|
```
|
14
14
|
|
15
|
-
### Configure
|
16
|
-
|
17
15
|
```bash
|
18
16
|
# Optional. When set, vault_client will ignore bad responses from The Vault's API.
|
19
17
|
# Default: false
|
@@ -27,42 +25,208 @@ $VAULT_URL=https://vault-stg.heroku.com
|
|
27
25
|
**Ruby configuration will take precedence over environment variables.**
|
28
26
|
|
29
27
|
```ruby
|
30
|
-
|
28
|
+
VC.url = "https://core:secret@vault-stg.heroku.com"
|
31
29
|
```
|
32
30
|
|
33
|
-
|
31
|
+
## Usage
|
32
|
+
|
33
|
+
### PaymentMethods
|
34
|
+
|
35
|
+
This API deals primarily with credit cards. PaymentMethods can be created
|
36
|
+
indipendintly of Accounts. You will need a payment_method to generate an
|
37
|
+
invoice.
|
38
|
+
|
39
|
+
```ruby
|
40
|
+
#TODO Build API
|
41
|
+
```
|
42
|
+
|
43
|
+
### Accounts
|
44
|
+
|
45
|
+
This API deals with accounts which is a primitive for grouping resources. You
|
46
|
+
will need an account to generate a usage report.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
VC::Account.create
|
50
|
+
#=> {:id => "001"}
|
51
|
+
```
|
52
|
+
|
53
|
+
### AccountOwnerships
|
54
|
+
|
55
|
+
Use this API when you want to setup associations between Vault accounts and
|
56
|
+
Vault payment_methods.
|
57
|
+
|
58
|
+
For complete details on the semantics of this API, read the [AccountOwnerships
|
59
|
+
API docs.](https://github.com/heroku/shushu/blob/master/doc/account_ownership_api.md)
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# To associate an account with a payment_method
|
63
|
+
VC::AcctOwn.act(
|
64
|
+
:account_id => vault_account_id,
|
65
|
+
:payment_method_id => payment_method_id,
|
66
|
+
:entity_id => entity_id,
|
67
|
+
:time => time
|
68
|
+
)
|
69
|
+
#=> {"payment_method_id"=>"123", "account_id"=>"1", "entity_id"=>"entity123"}
|
70
|
+
|
71
|
+
# Now we need to change the payment_method on an account
|
72
|
+
VC::AcctOwn.xfr(
|
73
|
+
:prev_payment_method_id => prev_payment_method_id,
|
74
|
+
:payment_method_id => new_payment_method_id,
|
75
|
+
:account_id => account_id,
|
76
|
+
:prev_entity_id => prev_entity_id,
|
77
|
+
:entity_id => entity_id,
|
78
|
+
:time => time
|
79
|
+
)
|
80
|
+
#=> {"payment_method_id"=>"456", "account_id"=>"1", "entity_id"=>"event124"}
|
81
|
+
```
|
82
|
+
|
83
|
+
### ResourceOwnerships
|
84
|
+
|
85
|
+
Use this API when dealing with resources and Vault accounts. For instance:
|
86
|
+
Heroku apps and Teams.
|
87
|
+
|
88
|
+
For complete details on the semantics of this API, read the [ResourceOwnerships
|
89
|
+
API docs.](https://github.com/heroku/shushu/blob/master/doc/resource_ownership_api.md)
|
34
90
|
|
35
91
|
```ruby
|
36
92
|
# When a new app is created, activate a new resource_ownership record.
|
37
|
-
|
38
|
-
|
93
|
+
VC::ResOwn.act(
|
94
|
+
:hid => hid,
|
95
|
+
:entity_id => entity_id,
|
96
|
+
:account_id => vault_account_id,
|
97
|
+
:time => time
|
98
|
+
)
|
99
|
+
#=> {"hid"=>"123", "account_id"=>"1", "entity_id"=>"event123"}
|
39
100
|
|
40
101
|
|
41
102
|
# When an app is transfered to another vault account, transfer the resource_ownership record.
|
42
|
-
|
43
|
-
|
103
|
+
VC::ResOwn.xfr(
|
104
|
+
:hid => hid,
|
105
|
+
:prev_entity_id => prev_entity_id,
|
106
|
+
:prev_vault_account_id => prev_vault_account_id,
|
107
|
+
:entity_id => entity_id,
|
108
|
+
:account_id => new_vault_account_id,
|
109
|
+
:time => time
|
110
|
+
)
|
111
|
+
#=> {"hid"=>"123", "account_id"=>"1", "entity_id"=>"event123"}
|
44
112
|
|
45
113
|
# When an app is destroyed, deactivate the resource_ownership record.
|
46
|
-
|
47
|
-
|
114
|
+
VC::ResOwn.deact(
|
115
|
+
:hid => hid,
|
116
|
+
:entity_id => entity_id,
|
117
|
+
:account_id => vault_account_id,
|
118
|
+
:time => time
|
119
|
+
)
|
120
|
+
#=> {"hid"=>"123", "account_id"=>"1", "entity_id"=>"event123"}
|
48
121
|
```
|
49
122
|
|
50
|
-
|
123
|
+
### BillableEvents
|
51
124
|
|
52
|
-
|
125
|
+
Use this API when you want to start billing for a resource. You can start
|
126
|
+
emitting events prior to setting up relationships between accounts and
|
127
|
+
payment_methods. (Although, usage reports and invoices will not be available
|
128
|
+
until account_ownerships and resource_ownerships have been established.)
|
53
129
|
|
54
|
-
|
55
|
-
|
56
|
-
the detail of the api. The aforementioned API client module should only return
|
57
|
-
the data that is needed by rest-client to submit the request.
|
130
|
+
For complete details on the semantics of this API, read the [BillableEvents
|
131
|
+
API docs.](https://github.com/heroku/shushu/blob/master/doc/events_api.md)
|
58
132
|
|
59
|
-
|
133
|
+
```ruby
|
134
|
+
# Open an event when you would like to start billing.
|
135
|
+
VC::BEvent.open(
|
136
|
+
:entity_id => entity_id,
|
137
|
+
:hid => hid,
|
138
|
+
:time => time,
|
139
|
+
:rate_code => rate_code,
|
140
|
+
:product_name => product_name,
|
141
|
+
:qty => qty
|
142
|
+
)
|
143
|
+
|
144
|
+
# Don't forget to close it.
|
145
|
+
VC::BEvent.close(
|
146
|
+
:entity_id => entity_id,
|
147
|
+
:time => time
|
148
|
+
)
|
149
|
+
```
|
60
150
|
|
61
|
-
|
62
|
-
for the http request. We trust that when rest-client is used correctly it will
|
63
|
-
work.
|
151
|
+
### UsageReports
|
64
152
|
|
65
|
-
```
|
66
|
-
|
67
|
-
|
153
|
+
```ruby
|
154
|
+
report = VC::UsageReport.new(account_id, from, to)
|
155
|
+
report.billable_units
|
156
|
+
```
|
157
|
+
|
158
|
+
|
159
|
+
### Invoices
|
160
|
+
|
161
|
+
```ruby
|
162
|
+
invoice = VC::UsageReport.new(account_id, from, to)
|
163
|
+
invoice.billable_units
|
68
164
|
```
|
165
|
+
|
166
|
+
|
167
|
+
### Report Generation
|
168
|
+
|
169
|
+
Invoices and UsageReports can be used for report generation. Basically, the
|
170
|
+
report generation code expects a collection of BillableUnits. BillableUnits are
|
171
|
+
returned from both the Invoice API and the UsageReport API. However, the details
|
172
|
+
of the billable_units may be different with respect to the type of the report.
|
173
|
+
|
174
|
+
#### Presenters
|
175
|
+
|
176
|
+
Clients of this library will want to generate some sort of view for the reports, the
|
177
|
+
presenter objects were created to aid with that effort. You should only need to
|
178
|
+
use the presenters while building views. Each view wraps a simple model object.
|
179
|
+
All of the models and presenters are derived from the billable_unit which is
|
180
|
+
retreived from the remote API.
|
181
|
+
|
182
|
+
Report --> LineItem --> UnitGroup --> Billable Unit
|
183
|
+
|
184
|
+
|
185
|
+
#### ReportPresenter
|
186
|
+
|
187
|
+
The report presenter is how you will kick off the process of generating a
|
188
|
+
report. You hand it a report object, either a UsageReport or and Invoice, and
|
189
|
+
using the reports billable_units, it will build the line_items and a set of
|
190
|
+
line_item_presenters for the line_items.
|
191
|
+
|
192
|
+
#### LineItemBuilder
|
193
|
+
|
194
|
+
The ReportPresenter will create a set of line_items based upon the
|
195
|
+
billable_units in the report. The default is to group things by HID. Thus there
|
196
|
+
will be a line_item for each distinct HID in the set of billable_units. The
|
197
|
+
builder will also give a collection of unit_groups to the line_item. By default,
|
198
|
+
the unit_groups will be partitioned by the product_group. (i.e. dyno, addon)
|
199
|
+
|
200
|
+
You can customize the LineItemBuilder by creating a new class that responds to
|
201
|
+
build and passing it to the ReportPresenter.
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
ReportPresenter.new(report, CustomLineItemBuilder)
|
205
|
+
```
|
206
|
+
|
207
|
+
#### LineItemPresenter
|
208
|
+
|
209
|
+
The LineItemPresenter is responsible for handling the total and names of the
|
210
|
+
line_items. It also manages the set of unit_groups. Since the default
|
211
|
+
LineItemBuilder partitioned unit_groups based upon product_group, you can ask
|
212
|
+
the LineItemPresenter for infomation about subsets of unit_groups. For instance:
|
213
|
+
|
214
|
+
```ruby
|
215
|
+
line_item_presenter.unit_group_presenters("dyno")
|
216
|
+
line_item_presenter.unit_group_total("dyno")
|
217
|
+
line_item_presenter.unit_group_qty("dyno")
|
218
|
+
```
|
219
|
+
|
220
|
+
|
221
|
+
#### UnitGroupPresenter
|
222
|
+
|
223
|
+
UnitGroups are collections of billable_units that are partitioned by
|
224
|
+
product_name. So if there exists a set of billable_units that all have
|
225
|
+
product_group = "dyno" and product_name= "worker", then this presenter
|
226
|
+
will give you information about that group.
|
227
|
+
|
228
|
+
|
229
|
+
#### UnitPresenter
|
230
|
+
|
231
|
+
Finally, the UnitPresenter wraps a billable_unit and exposes methods to show
|
232
|
+
totals, quantities and other meta-data.
|