vault_client 0.0.3 → 0.1.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.
- 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.
|