tools-cf-plugin 2.3.0 → 2.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -5,7 +5,7 @@ module CFTools
5
5
  class DEAApps < CF::App::Base
6
6
  def precondition; end
7
7
 
8
- desc "Show an overview of DEA advertisements over time."
8
+ desc "Show an overview of running applications."
9
9
  group :admin
10
10
  input :host, :alias => "-h", :default => "127.0.0.1",
11
11
  :desc => "NATS server address"
@@ -15,95 +15,174 @@ module CFTools
15
15
  :desc => "NATS server user"
16
16
  input :password, :alias => "-p", :default => "nats",
17
17
  :desc => "NATS server password"
18
+ input :location, :alias => "-l", :default => false,
19
+ :desc => "Include application's location (org/space)"
20
+ input :stats, :alias => "-s", :default => false,
21
+ :desc => "Include application's runtime stats"
18
22
  def dea_apps
19
- @seen_apps = {}
20
-
21
23
  host = input[:host]
22
24
  port = input[:port]
23
25
  user = input[:user]
24
26
  pass = input[:password]
25
27
 
26
- render_apps("nats://#{user}:#{pass}@#{host}:#{port}")
28
+ render_apps(
29
+ "nats://#{user}:#{pass}@#{host}:#{port}",
30
+ :include_location => input[:location],
31
+ :include_stats => input[:stats])
27
32
  end
28
33
 
29
- def render_apps(uri)
34
+ private
35
+
36
+ def render_apps(uri, options = {})
30
37
  NATS.start(:uri => uri) do
31
- NATS.subscribe("dea.advertise") do |msg|
38
+ NATS.subscribe("dea.heartbeat") do |msg|
32
39
  payload = JSON.parse(msg)
33
- dea_id = payload["id"]
34
- advertisements[dea_id] = payload["app_id_to_count"]
40
+ dea_id = payload["dea"]
41
+ register_heartbeat(dea_id, payload["droplets"])
35
42
  end
36
43
 
37
44
  EM.add_periodic_timer(3) do
38
- render_table
45
+ render_table(options)
39
46
  end
40
47
  end
41
48
  rescue NATS::ServerError => e
42
- if e.to_s =~ /slow consumer/i
49
+ if e.to_s =~ /connection dropped/i
43
50
  line c("dropped by server; reconnecting...", :error)
44
51
  retry
52
+ else
53
+ raise
45
54
  end
46
55
  end
47
56
 
48
- private
57
+ def register_heartbeat(dea, droplets)
58
+ heartbeats[dea] ||= {}
59
+
60
+ droplets.each do |droplet|
61
+ if %w[RUNNING STARTING STOPPING].include?(droplet["state"])
62
+ heartbeats[dea][droplet["instance"]] = droplet
63
+ else
64
+ heartbeats[dea].delete(droplet["instance"])
65
+ end
66
+ end
67
+ end
68
+
69
+ def seen_apps
70
+ @seen_apps ||= {}
71
+ end
72
+
73
+ def heartbeats
74
+ @heartbeats ||= {}
75
+ end
49
76
 
50
77
  def client_app(guid)
51
78
  existing_app =
52
- if @seen_apps.key?(guid)
53
- @seen_apps[guid]
79
+ if seen_apps.key?(guid)
80
+ seen_apps[guid]
54
81
  else
55
82
  app = client.app(guid, :depth => 2)
56
83
  app if app.exists?
57
84
  end
58
85
 
59
- @seen_apps[guid] = existing_app
86
+ seen_apps[guid] = existing_app
60
87
  end
61
88
 
62
- def advertisements
63
- @advertisements ||= {}
64
- end
89
+ def render_table(options = {})
90
+ include_location = options[:include_location]
91
+ include_stats = options[:include_stats]
65
92
 
66
- def render_table
67
93
  app_counts = Hash.new(0)
68
94
  app_deas = Hash.new { |h, k| h[k] = [] }
69
95
 
70
- advertisements.each do |dea_id, counts|
71
- counts.each do |app_guid, count|
72
- app_counts[app_guid] += count
96
+ heartbeats.each do |dea_id, droplets|
97
+ droplets.each_value do |droplet|
98
+ app_guid = droplet["droplet"]
99
+ app_counts[app_guid] += 1
73
100
  app_deas[app_guid] << dea_id
74
101
  end
75
102
  end
76
103
 
104
+ columns = %w[dea app guid reserved math]
105
+
106
+ columns << "stats" if include_stats
107
+ columns << "org/space" if include_location
108
+
77
109
  rows = app_counts.sort_by { |app_guid, count|
78
- app = client_app(app_guid)
79
- app ? app.memory * count : 0
80
- }.reverse.collect do |app_guid, count|
81
- app = client_app(app_guid)
82
-
83
- deas = list(app_deas[app_guid].collect(&:to_i).sort)
84
-
85
- if app
86
- [
87
- "#{b(deas)}",
88
- "#{c(app.name, :name)}",
89
- "#{app.guid}",
90
- "#{c(app.space.organization.name, :name)} / #{c(app.space.name, :name)}",
91
- "#{human_mb(app.memory * count)}",
92
- "(#{human_mb(app.memory)} x #{count})"
93
- ]
110
+ if seen_apps.key?(app_guid)
111
+ app = client_app(app_guid)
112
+ app ? app.memory * count : 0
94
113
  else
95
- [
96
- "#{b(deas)}",
97
- c("unknown", :warning),
98
- "#{app_guid}",
99
- "?",
100
- "?",
101
- "(? x #{count})"
102
- ]
114
+ 0
115
+ end
116
+ }.collect do |app_guid, count|
117
+ proc do
118
+ app = client_app(app_guid)
119
+
120
+ deas = list(app_deas[app_guid].collect(&:to_i).sort)
121
+
122
+ row =
123
+ if app
124
+ [
125
+ "#{b(deas)}",
126
+ "#{c(app.name, :name)}",
127
+ "#{app.guid}",
128
+ "#{human_mb(app.memory * count)}",
129
+ "(#{human_mb(app.memory)} x #{count})",
130
+ ]
131
+ else
132
+ [
133
+ "#{b(deas)}",
134
+ c("unknown", :warning),
135
+ "#{app_guid}",
136
+ "?",
137
+ "(? x #{count})",
138
+ ]
139
+ end
140
+
141
+ if include_stats && app
142
+ row << app_stats(app)
143
+ end
144
+
145
+ if include_location && app
146
+ row << "#{c(app.space.organization.name, :name)} / #{c(app.space.name, :name)}"
147
+ end
148
+
149
+ row
103
150
  end
104
151
  end
105
152
 
106
- table(["dea", "app_name", "app_guid", "org/space", "reserved", "math"], rows)
153
+ apps_table.render([columns] + rows)
154
+ end
155
+
156
+ def apps_table
157
+ @apps_table ||= AppsTable.new
158
+ end
159
+
160
+ def app_stats(app)
161
+ app.stats.sort_by(&:first).collect do |index, info|
162
+ if info[:state] == "RUNNING"
163
+ "%s: %s" % [index, percentage(info[:stats][:usage][:cpu] * 100)]
164
+ else
165
+ "%s: %s" % [
166
+ index,
167
+ c(info[:state].downcase, state_color(info[:state]))
168
+ ]
169
+ end
170
+ end.join(", ")
171
+ rescue CFoundry::StatsError, CFoundry::AppNotFound
172
+ d("unknown")
173
+ end
174
+
175
+ def percentage(num, low = 10, mid = 70)
176
+ color =
177
+ if num <= low
178
+ :good
179
+ elsif num <= mid
180
+ :warning
181
+ else
182
+ :bad
183
+ end
184
+
185
+ c(format("%.1f\%", num), color)
107
186
  end
108
187
 
109
188
  def human_mb(mem)
@@ -132,5 +211,40 @@ module CFTools
132
211
  vals.join(",")
133
212
  end
134
213
  end
214
+
215
+ class AppsTable
216
+ include CF::Spacing
217
+
218
+ def spacings
219
+ @spacings ||= Hash.new(0)
220
+ end
221
+
222
+ def render(rows)
223
+ num_columns = rows.first ? rows.first.size : 0
224
+
225
+ rows.each do |row|
226
+ next unless row
227
+ row = row.call if row.respond_to?(:call)
228
+
229
+ start_line("")
230
+
231
+ row.each.with_index do |col, i|
232
+ next unless col
233
+
234
+ width = text_width(col)
235
+ spacings[i] = width if width > spacings[i]
236
+
237
+ if i + 1 == num_columns
238
+ print col
239
+ else
240
+ print justify(col, spacings[i])
241
+ print " "
242
+ end
243
+ end
244
+
245
+ line
246
+ end
247
+ end
248
+ end
135
249
  end
136
250
  end
@@ -1,6 +1,5 @@
1
1
  require "cf/cli"
2
2
  require "pry"
3
- require "cli"
4
3
 
5
4
  module CFTools
6
5
  class Shell < CF::CLI
@@ -1,5 +1,4 @@
1
1
  require "yaml"
2
- require "cli"
3
2
  require "net/ssh/gateway"
4
3
 
5
4
  require "cf/cli"
@@ -8,8 +7,9 @@ module CFTools
8
7
  module Tunnel
9
8
  class Base < CF::CLI
10
9
  BOSH_CONFIG = "~/.bosh_config"
11
-
10
+
12
11
  def precondition
12
+ require "cli"
13
13
  end
14
14
 
15
15
  def director(director_host, gateway)
@@ -1,5 +1,4 @@
1
1
  require "yaml"
2
- require "cli"
3
2
  require "net/ssh"
4
3
 
5
4
  require "cf/cli"
@@ -41,7 +40,7 @@ module CFTools::Tunnel
41
40
 
42
41
  nport =
43
42
  with_progress("Opening local tunnel to NATS") do
44
- tunnel_to(nats["address"], nats["port"], gateway)
43
+ tunnel_to(nats["address"], nats["port"], gateway)
45
44
  end
46
45
 
47
46
  with_progress("Logging in as admin user") do
@@ -1,3 +1,3 @@
1
1
  module CFTools
2
- VERSION = "2.3.0".freeze
2
+ VERSION = "2.4.0".freeze
3
3
  end
@@ -1,11 +1,23 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe CFTools::DEAApps do
4
- let(:app1) { fake :app, :name => "myapp1", :guid => "myappguid-1", :memory => 128, :total_instances => 4 }
5
- let(:app2) { fake :app, :name => "myapp2", :guid => "myappguid-2", :memory => 256, :total_instances => 4 }
6
- let(:app3) { fake :app, :name => "myapp3", :guid => "myappguid-3", :memory => 1024, :total_instances => 4 }
7
4
  let(:client) { fake_client :apps => [app1, app2, app3] }
8
5
 
6
+ let(:app1) do
7
+ fake :app, :name => "myapp1", :guid => "myappguid-1",
8
+ :memory => 128, :total_instances => 1
9
+ end
10
+
11
+ let(:app2) do
12
+ fake :app, :name => "myapp2", :guid => "myappguid-2",
13
+ :memory => 256, :total_instances => 2
14
+ end
15
+
16
+ let(:app3) do
17
+ fake :app, :name => "myapp3", :guid => "myappguid-3",
18
+ :memory => 1024, :total_instances => 4
19
+ end
20
+
9
21
  before { stub_client }
10
22
 
11
23
  before do
@@ -20,39 +32,175 @@ describe CFTools::DEAApps do
20
32
  EM.stub(:add_periodic_timer).and_yield
21
33
  end
22
34
 
23
- let(:advertise) { <<PAYLOAD }
35
+ let(:heartbeat) { <<PAYLOAD }
24
36
  {
25
- "app_id_to_count": {
26
- "#{app1.guid}": #{app1.total_instances},
27
- "#{app2.guid}": #{app2.total_instances},
28
- "#{app3.guid}": #{app3.total_instances}
29
- },
30
- "available_memory": 1256,
31
- "stacks": [
32
- "lucid64",
33
- "lucid86"
34
- ],
35
37
  "prod": false,
36
- "id": "2-1d0cf3bcd994d9f2c5ea22b9b624d77b"
38
+ "dea": "2-4b293b726167fbc895af5a7927c0973a",
39
+ "droplets": [
40
+ {
41
+ "state_timestamp": 1369251231.3436642,
42
+ "state": "RUNNING",
43
+ "index": 0,
44
+ "instance": "app1-instance1",
45
+ "version": "5c0e0e10-8384-4a35-915e-872fe91ffb95",
46
+ "droplet": "#{app1.guid}",
47
+ "cc_partition": "default"
48
+ },
49
+ {
50
+ "state_timestamp": 1369251231.3436642,
51
+ "state": "CRASHED",
52
+ "index": 1,
53
+ "instance": "app2-dead-isntance",
54
+ "version": "deadbeef-8384-4a35-915e-872fe91ffb95",
55
+ "droplet": "#{app2.guid}",
56
+ "cc_partition": "default"
57
+ },
58
+ {
59
+ "state_timestamp": 1369251231.3436642,
60
+ "state": "RUNNING",
61
+ "index": 1,
62
+ "instance": "app2-instance1",
63
+ "version": "deadbeef-8384-4a35-915e-872fe91ffb95",
64
+ "droplet": "#{app2.guid}",
65
+ "cc_partition": "default"
66
+ },
67
+ {
68
+ "state_timestamp": 1369251231.3436642,
69
+ "state": "RUNNING",
70
+ "index": 1,
71
+ "instance": "app2-instance2",
72
+ "version": "deadbeef-8384-4a35-915e-872fe91ffb95",
73
+ "droplet": "#{app2.guid}",
74
+ "cc_partition": "default"
75
+ },
76
+ {
77
+ "state_timestamp": 1369251225.2800167,
78
+ "state": "RUNNING",
79
+ "index": 0,
80
+ "instance": "app3-instance1",
81
+ "version": "bdc3b7d7-5a55-455d-ac66-ba82a9ad43e7",
82
+ "droplet": "#{app3.guid}",
83
+ "cc_partition": "default"
84
+ },
85
+ {
86
+ "state_timestamp": 1369251225.2800167,
87
+ "state": "RUNNING",
88
+ "index": 0,
89
+ "instance": "app3-instance2",
90
+ "version": "bdc3b7d7-5a55-455d-ac66-ba82a9ad43e7",
91
+ "droplet": "#{app3.guid}",
92
+ "cc_partition": "default"
93
+ },
94
+ {
95
+ "state_timestamp": 1369251225.2800167,
96
+ "state": "RUNNING",
97
+ "index": 0,
98
+ "instance": "app3-instance3",
99
+ "version": "bdc3b7d7-5a55-455d-ac66-ba82a9ad43e7",
100
+ "droplet": "#{app3.guid}",
101
+ "cc_partition": "default"
102
+ },
103
+ {
104
+ "state_timestamp": 1369251225.2800167,
105
+ "state": "RUNNING",
106
+ "index": 0,
107
+ "instance": "app3-instance4",
108
+ "version": "bdc3b7d7-5a55-455d-ac66-ba82a9ad43e7",
109
+ "droplet": "#{app3.guid}",
110
+ "cc_partition": "default"
111
+ }
112
+ ]
37
113
  }
38
114
  PAYLOAD
39
115
 
40
116
  before do
41
- NATS.stub(:subscribe).and_yield(advertise)
117
+ NATS.stub(:subscribe).and_yield(heartbeat)
42
118
  end
43
119
 
44
120
  it "outputs the list of apps, memory and math" do
45
121
  cf %W[dea-apps]
46
- expect(output).to say(%r{app_name\s+app_guid\s+org/space\s+reserved\s+math})
47
- expect(output).to say(%r{myapp3\s+myappguid-3\s+organization-\w+ / space-\w+\s+4G\s+\(1G\s+x\s+4\)})
48
- expect(output).to say(%r{myapp2\s+myappguid-2\s+organization-\w+ / space-\w+\s+1G\s+\(256M\s+x\s+4\)})
49
- expect(output).to say(%r{myapp1\s+myappguid-1\s+organization-\w+ / space-\w+\s+512M\s+\(128M\s+x\s+4\)})
122
+ expect(output).to say(%r{dea\s+app\s+guid\s+reserved\s+math})
123
+ expect(output).to say(%r{2\s+myapp1\s+myappguid-1\s+128M\s+\(128M\s+x\s+1\)})
124
+ expect(output).to say(%r{2\s+myapp2\s+myappguid-2\s+512M\s+\(256M\s+x\s+2\)})
125
+ expect(output).to say(%r{2\s+myapp3\s+myappguid-3\s+4G\s+\(1G\s+x\s+4\)})
126
+ end
127
+
128
+ context "when --location is provided" do
129
+ it "includes the org and space in the table" do
130
+ cf %W[dea-apps --location]
131
+ expect(output).to say(%r{^.*\s+org/space})
132
+ expect(output).to say(%r{^.*\s+#{app1.space.organization.name} / #{app1.space.name}})
133
+ expect(output).to say(%r{^.*\s+#{app2.space.organization.name} / #{app2.space.name}})
134
+ expect(output).to say(%r{^.*\s+#{app3.space.organization.name} / #{app3.space.name}})
135
+ end
136
+ end
137
+
138
+ context "when --stats is provided" do
139
+ before do
140
+ stub_request(:get, "#{client.target}/v2/apps/#{app1.guid}/stats").
141
+ to_return(
142
+ :status => 200,
143
+ :body => File.read(fixture("dea-apps/stats_1.json")))
144
+
145
+ stub_request(:get, "#{client.target}/v2/apps/#{app2.guid}/stats").
146
+ to_return(
147
+ :status => 200,
148
+ :body => File.read(fixture("dea-apps/stats_2.json")))
149
+
150
+ stub_request(:get, "#{client.target}/v2/apps/#{app3.guid}/stats").
151
+ to_return(
152
+ :status => 200,
153
+ :body => File.read(fixture("dea-apps/stats_3.json")))
154
+ end
155
+
156
+ it "includes the the app's running stats" do
157
+ cf %W[dea-apps --stats]
158
+ expect(output).to say(%r{^.*\s+stats})
159
+ expect(output).to say(%r{^.*\s+0: 1\.2%})
160
+ expect(output).to say(%r{^.*\s+0: 100\.0%, 1: 50\.0%})
161
+ expect(output).to say(%r{^.*\s+0: 11\.2%, 1: 6\.1%, 2: 12\.5%})
162
+ end
163
+
164
+ context "and an instance is down" do
165
+ before do
166
+ stub_request(:get, "#{client.target}/v2/apps/#{app3.guid}/stats").
167
+ to_return(
168
+ :status => 200,
169
+ :body => File.read(fixture("dea-apps/stats_3_down.json")))
170
+ end
171
+
172
+ it "prints the state as down for that index" do
173
+ cf %W[dea-apps --stats]
174
+ expect(output).to say(%r{^.*\s+stats})
175
+ expect(output).to say(%r{^.*\s+0: 11\.2%, 1: down, 2: 12\.5%})
176
+ end
177
+ end
178
+
179
+ context "and an app is stopped by the time we request the stats" do
180
+ it "prints the state as down for that index" do
181
+ expect(app1).to receive(:stats).and_raise(CFoundry::StatsError)
182
+
183
+ cf %W[dea-apps --stats]
184
+ expect(output).to say(%r{^.*\s+stats})
185
+ expect(output).to say(%r{^.*\s+unknown})
186
+ end
187
+ end
188
+
189
+ context "and an app is deleted by the time we request the stats" do
190
+ it "prints the state as down for that index" do
191
+ expect(app1).to receive(:stats).and_raise(CFoundry::AppNotFound)
192
+
193
+ cf %W[dea-apps --stats]
194
+ expect(output).to say(%r{^.*\s+stats})
195
+ expect(output).to say(%r{^.*\s+unknown})
196
+ end
197
+ end
50
198
  end
51
199
 
52
- context "when the server drops us for being a slow consumer" do
200
+ context "when the server drops the connection" do
53
201
  it "reconnects" do
54
202
  expect(NATS).to receive(:subscribe).and_raise(
55
- NATS::ServerError, "Slow consumer detected, connection dropped")
203
+ NATS::ServerError, "connection dropped")
56
204
 
57
205
  expect(NATS).to receive(:start).twice
58
206
 
@@ -61,7 +209,7 @@ PAYLOAD
61
209
 
62
210
  it "says it's reconnecting" do
63
211
  expect(NATS).to receive(:subscribe).and_raise(
64
- NATS::ServerError, "Slow consumer detected, connection dropped")
212
+ NATS::ServerError, "connection dropped")
65
213
 
66
214
  cf %W[dea-apps]
67
215
 
@@ -0,0 +1,21 @@
1
+ {
2
+ "0": {
3
+ "state": "RUNNING",
4
+ "stats": {
5
+ "name": "myapp1",
6
+ "uris": [],
7
+ "host": "10.10.17.15",
8
+ "port": 61475,
9
+ "uptime": 92443,
10
+ "mem_quota": 268435456,
11
+ "disk_quota": 1073741824,
12
+ "fds_quota": 16384,
13
+ "usage": {
14
+ "time": "2013-07-06 21:51:06 +0000",
15
+ "cpu": 0.0121223756854101324,
16
+ "mem": 14925824,
17
+ "disk": 76001280
18
+ }
19
+ }
20
+ }
21
+ }
@@ -0,0 +1,40 @@
1
+ {
2
+ "1": {
3
+ "state": "RUNNING",
4
+ "stats": {
5
+ "name": "myapp2",
6
+ "uris": [],
7
+ "host": "10.10.17.7",
8
+ "port": 61215,
9
+ "uptime": 92876,
10
+ "mem_quota": 268435456,
11
+ "disk_quota": 1073741824,
12
+ "fds_quota": 16384,
13
+ "usage": {
14
+ "time": "2013-07-06 21:51:06 +0000",
15
+ "cpu": 0.5,
16
+ "mem": 14938112,
17
+ "disk": 76001280
18
+ }
19
+ }
20
+ },
21
+ "0": {
22
+ "state": "RUNNING",
23
+ "stats": {
24
+ "name": "myapp2",
25
+ "uris": [],
26
+ "host": "10.10.17.15",
27
+ "port": 61475,
28
+ "uptime": 92443,
29
+ "mem_quota": 268435456,
30
+ "disk_quota": 1073741824,
31
+ "fds_quota": 16384,
32
+ "usage": {
33
+ "time": "2013-07-06 21:51:06 +0000",
34
+ "cpu": 1.0,
35
+ "mem": 14925824,
36
+ "disk": 76001280
37
+ }
38
+ }
39
+ }
40
+ }
@@ -0,0 +1,59 @@
1
+ {
2
+ "2": {
3
+ "state": "RUNNING",
4
+ "stats": {
5
+ "name": "myapp3",
6
+ "uris": [],
7
+ "host": "10.10.17.8",
8
+ "port": 61573,
9
+ "uptime": 92003,
10
+ "mem_quota": 268435456,
11
+ "disk_quota": 1073741824,
12
+ "fds_quota": 16384,
13
+ "usage": {
14
+ "time": "2013-07-06 21:51:06 +0000",
15
+ "cpu": 0.125,
16
+ "mem": 15622144,
17
+ "disk": 76009472
18
+ }
19
+ }
20
+ },
21
+ "1": {
22
+ "state": "RUNNING",
23
+ "stats": {
24
+ "name": "myapp3",
25
+ "uris": [],
26
+ "host": "10.10.17.7",
27
+ "port": 61215,
28
+ "uptime": 92876,
29
+ "mem_quota": 268435456,
30
+ "disk_quota": 1073741824,
31
+ "fds_quota": 16384,
32
+ "usage": {
33
+ "time": "2013-07-06 21:51:06 +0000",
34
+ "cpu": 0.06125,
35
+ "mem": 14938112,
36
+ "disk": 76001280
37
+ }
38
+ }
39
+ },
40
+ "0": {
41
+ "state": "RUNNING",
42
+ "stats": {
43
+ "name": "myapp3",
44
+ "uris": [],
45
+ "host": "10.10.17.15",
46
+ "port": 61475,
47
+ "uptime": 92443,
48
+ "mem_quota": 268435456,
49
+ "disk_quota": 1073741824,
50
+ "fds_quota": 16384,
51
+ "usage": {
52
+ "time": "2013-07-06 21:51:06 +0000",
53
+ "cpu": 0.1123,
54
+ "mem": 14925824,
55
+ "disk": 76001280
56
+ }
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,44 @@
1
+ {
2
+ "2": {
3
+ "state": "RUNNING",
4
+ "stats": {
5
+ "name": "myapp3",
6
+ "uris": [],
7
+ "host": "10.10.17.8",
8
+ "port": 61573,
9
+ "uptime": 92003,
10
+ "mem_quota": 268435456,
11
+ "disk_quota": 1073741824,
12
+ "fds_quota": 16384,
13
+ "usage": {
14
+ "time": "2013-07-06 21:51:06 +0000",
15
+ "cpu": 0.125,
16
+ "mem": 15622144,
17
+ "disk": 76009472
18
+ }
19
+ }
20
+ },
21
+ "1": {
22
+ "state": "DOWN",
23
+ "since": 1373149320
24
+ },
25
+ "0": {
26
+ "state": "RUNNING",
27
+ "stats": {
28
+ "name": "myapp3",
29
+ "uris": [],
30
+ "host": "10.10.17.15",
31
+ "port": 61475,
32
+ "uptime": 92443,
33
+ "mem_quota": 268435456,
34
+ "disk_quota": 1073741824,
35
+ "fds_quota": 16384,
36
+ "usage": {
37
+ "time": "2013-07-06 21:51:06 +0000",
38
+ "cpu": 0.1123,
39
+ "mem": 14925824,
40
+ "disk": 76001280
41
+ }
42
+ }
43
+ }
44
+ }
data/spec/spec_helper.rb CHANGED
@@ -9,6 +9,8 @@ require "webmock/rspec"
9
9
  require "cf/test_support"
10
10
  require "blue-shell"
11
11
  require "nats/client"
12
+ require "cli" # BOSH
13
+ # yes really
12
14
 
13
15
  require "#{SPEC_ROOT}/../lib/tools-cf-plugin/plugin"
14
16
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tools-cf-plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-05 00:00:00.000000000 Z
12
+ date: 2013-07-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: cfoundry
@@ -43,28 +43,6 @@ dependencies:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
45
  version: '0'
46
- - !ruby/object:Gem::Dependency
47
- name: bosh_cli
48
- requirement: !ruby/object:Gem::Requirement
49
- none: false
50
- requirements:
51
- - - ! '>='
52
- - !ruby/object:Gem::Version
53
- version: 1.5.0.pre.3
54
- - - <
55
- - !ruby/object:Gem::Version
56
- version: '1.6'
57
- type: :runtime
58
- prerelease: false
59
- version_requirements: !ruby/object:Gem::Requirement
60
- none: false
61
- requirements:
62
- - - ! '>='
63
- - !ruby/object:Gem::Version
64
- version: 1.5.0.pre.3
65
- - - <
66
- - !ruby/object:Gem::Version
67
- version: '1.6'
68
46
  - !ruby/object:Gem::Dependency
69
47
  name: net-ssh
70
48
  requirement: !ruby/object:Gem::Requirement
@@ -286,6 +264,10 @@ files:
286
264
  - lib/tools-cf-plugin/watch.rb
287
265
  - spec/dea-ads_spec.rb
288
266
  - spec/dea-apps_spec.rb
267
+ - spec/fixtures/dea-apps/stats_1.json
268
+ - spec/fixtures/dea-apps/stats_2.json
269
+ - spec/fixtures/dea-apps/stats_3.json
270
+ - spec/fixtures/dea-apps/stats_3_down.json
289
271
  - spec/fixtures/nats_logs/1
290
272
  - spec/fixtures/spacetime/1
291
273
  - spec/shell_spec.rb
@@ -325,6 +307,10 @@ summary: Cloud Foundry tooling commands.
325
307
  test_files:
326
308
  - spec/dea-ads_spec.rb
327
309
  - spec/dea-apps_spec.rb
310
+ - spec/fixtures/dea-apps/stats_1.json
311
+ - spec/fixtures/dea-apps/stats_2.json
312
+ - spec/fixtures/dea-apps/stats_3.json
313
+ - spec/fixtures/dea-apps/stats_3_down.json
328
314
  - spec/fixtures/nats_logs/1
329
315
  - spec/fixtures/spacetime/1
330
316
  - spec/shell_spec.rb
@@ -337,3 +323,4 @@ test_files:
337
323
  - spec/tunnel/tunnel-nats_spec.rb
338
324
  - spec/tunnel/watch-logs_spec.rb
339
325
  - spec/watch_spec.rb
326
+ has_rdoc: