opsicle 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +3 -0
  3. data/.travis.yml +6 -1
  4. data/Gemfile +3 -0
  5. data/Guardfile +5 -0
  6. data/README.markdown +44 -17
  7. data/bin/opsicle +36 -3
  8. data/lib/opsicle.rb +2 -3
  9. data/lib/opsicle/commands.rb +6 -0
  10. data/lib/opsicle/commands/deploy.rb +39 -0
  11. data/lib/opsicle/{list.rb → commands/list.rb} +0 -2
  12. data/lib/opsicle/{ssh.rb → commands/ssh.rb} +0 -3
  13. data/lib/opsicle/commands/ssh_key.rb +40 -0
  14. data/lib/opsicle/config.rb +1 -0
  15. data/lib/opsicle/deployment.rb +59 -0
  16. data/lib/opsicle/deployments.rb +22 -0
  17. data/lib/opsicle/monitor.rb +12 -0
  18. data/lib/opsicle/monitor/app.rb +147 -0
  19. data/lib/opsicle/monitor/panel.rb +98 -0
  20. data/lib/opsicle/monitor/panels/deployments.rb +42 -0
  21. data/lib/opsicle/monitor/panels/header.rb +48 -0
  22. data/lib/opsicle/monitor/panels/help.rb +33 -0
  23. data/lib/opsicle/monitor/screen.rb +83 -0
  24. data/lib/opsicle/monitor/spy/dataspyable.rb +19 -0
  25. data/lib/opsicle/monitor/spy/deployments.rb +53 -0
  26. data/lib/opsicle/monitor/subpanel.rb +55 -0
  27. data/lib/opsicle/monitor/translatable.rb +33 -0
  28. data/lib/opsicle/stack.rb +22 -0
  29. data/lib/opsicle/version.rb +1 -1
  30. data/opsicle.gemspec +1 -1
  31. data/spec/opsicle/client_spec.rb +6 -6
  32. data/spec/opsicle/commands/deploy_spec.rb +50 -0
  33. data/spec/opsicle/{list_spec.rb → commands/list_spec.rb} +7 -6
  34. data/spec/opsicle/commands/ssh_key_spec.rb +75 -0
  35. data/spec/opsicle/{ssh_spec.rb → commands/ssh_spec.rb} +24 -24
  36. data/spec/opsicle/config_spec.rb +12 -11
  37. data/spec/opsicle/monitor/app_spec.rb +63 -0
  38. data/spec/opsicle/monitor/panel_spec.rb +162 -0
  39. data/spec/opsicle/monitor/screen_spec.rb +121 -0
  40. data/spec/opsicle/monitor/spy/deployments_spec.rb +41 -0
  41. data/spec/opsicle/monitor/subpanel_spec.rb +199 -0
  42. data/spec/spec_helper.rb +2 -1
  43. metadata +44 -16
  44. data/Gemfile.lock +0 -75
  45. data/lib/opsicle/deploy.rb +0 -25
  46. data/spec/opsicle/deploy_spec.rb +0 -29
@@ -0,0 +1,162 @@
1
+ require "spec_helper"
2
+ require "opsicle/monitor/panel"
3
+ require "curses"
4
+
5
+
6
+ describe Opsicle::Monitor::Panel do
7
+
8
+ before do
9
+ @window = double
10
+
11
+ allow(Curses::Window).to receive(:new).and_return(@window)
12
+
13
+ @panel = Opsicle::Monitor::Panel.new(24, 80, 1, 2)
14
+ end
15
+
16
+ describe "#initialize" do
17
+ describe "required" do
18
+ it "sets height" do
19
+ expect(@panel.height).to equal(24)
20
+ end
21
+
22
+ it "sets width" do
23
+ expect(@panel.width).to equal(80)
24
+ end
25
+
26
+ it "sets top" do
27
+ expect(@panel.top).to equal(1)
28
+ end
29
+
30
+ it "sets left" do
31
+ expect(@panel.left).to equal(2)
32
+ end
33
+
34
+ it "defaults dividers" do
35
+ expect(@panel.dividers).to eq({
36
+ :left => '',
37
+ :right => '',
38
+ })
39
+ end
40
+
41
+ it "calculates divider_length" do
42
+ expect(@panel.divider_length).to equal(0)
43
+ end
44
+
45
+
46
+ it "sets up window with dimensions" do
47
+ expect(Curses::Window).to receive(:new).with(24,80,1,2)
48
+
49
+ Opsicle::Monitor::Panel.new(24, 80, 1, 2)
50
+ end
51
+
52
+ it "sets window" do
53
+ expect(@panel.instance_variable_get(:@window)).to eq(@window)
54
+ end
55
+ end
56
+
57
+ describe "optional" do
58
+ before do
59
+ @structure = [
60
+ [
61
+ [1, "busy:", -> { 1 + 3 }], # S(0,0)
62
+ [1, "retries:", 2], # S(0,1)
63
+ ],
64
+ [
65
+ [2, -> { 2 * 7 }, "long"], # S(1,0)
66
+ [1, -> { "1" + "4" }, -> { "dark" }], # S(1,1)
67
+ ],
68
+ ]
69
+
70
+ @panel = Opsicle::Monitor::Panel.new(24, 80, 1, 2, @structure,
71
+ :divider_l => '<',
72
+ :divider_r => '>'
73
+ )
74
+
75
+ @subpanels = @panel.instance_variable_get(:@subpanels)
76
+ end
77
+
78
+ it "sets dividers" do
79
+ expect(@panel.dividers).to eq({
80
+ :left => '<',
81
+ :right => '>',
82
+ })
83
+ end
84
+
85
+ it "calculates divider_length" do
86
+ expect(@panel.divider_length).to equal(2)
87
+ end
88
+
89
+ it "builds enough subpanels" do
90
+ expect(@subpanels.length).to equal(4)
91
+ end
92
+
93
+ it "builds S(0,0)" do
94
+ expect(@subpanels.count { |e|
95
+ e.height == 1 && e.width == 42 && e.top == 0 && e.left == 0 &&
96
+ e.data[:left] == "busy:" && e.data[:right].call == 4 &&
97
+ e.dividers[:left] == '' && e.dividers[:right] == '>' &&
98
+ e.content_width == 41
99
+ }).to equal(1)
100
+ end
101
+
102
+ it "builds S(0,1)" do
103
+ expect(@subpanels.count { |e|
104
+ e.height == 1 && e.width == 38 && e.top == 0 && e.left == 42 &&
105
+ e.data[:left] == "retries:" && e.data[:right] == 2 &&
106
+ e.dividers[:left] == '<' && e.dividers[:right] == '' &&
107
+ e.content_width == 37
108
+ }).to equal(1)
109
+ end
110
+
111
+ it "builds S(1,0)" do
112
+ expect(@subpanels.count { |e|
113
+ e.height == 1 && e.width == 56 && e.top == 1 && e.left == 0 &&
114
+ e.data[:left].call == 14 && e.data[:right] == "long" &&
115
+ e.dividers[:left] == '' && e.dividers[:right] == '>' &&
116
+ e.content_width == 55
117
+ }).to equal(1)
118
+ end
119
+
120
+ it "builds S(1,1)" do
121
+ expect(@subpanels.count { |e|
122
+ e.height == 1 && e.width == 24 && e.top == 1 && e.left == 56 &&
123
+ e.data[:left].call == "14" && e.data[:right].call == "dark" &&
124
+ e.dividers[:left] == '<' && e.dividers[:right] == '' &&
125
+ e.content_width == 23
126
+ }).to equal(1)
127
+ end
128
+ end
129
+ end
130
+
131
+ describe "#close" do
132
+ it "closes window" do
133
+ expect(@window).to receive(:close)
134
+
135
+ @panel.close
136
+ end
137
+ end
138
+
139
+ describe "#refresh" do
140
+ it "refreshes subpanels" do
141
+ allow(@window).to receive(:refresh)
142
+
143
+ @subpanel2 = double
144
+ expect(@subpanel2).to receive(:refresh)
145
+
146
+ @panel.instance_variable_set(:@subpanels, [@subpanel2])
147
+
148
+ @panel.refresh
149
+ end
150
+
151
+ it "refreshes window" do
152
+ @subpanel2 = double(:refresh => nil)
153
+
154
+ @panel.instance_variable_set(:@subpanels, [@subpanel2])
155
+
156
+ expect(@window).to receive(:refresh)
157
+
158
+ @panel.refresh
159
+ end
160
+ end
161
+
162
+ end
@@ -0,0 +1,121 @@
1
+ require "spec_helper"
2
+ require "opsicle/monitor/screen"
3
+ require "opsicle/monitor/panels/header"
4
+ require "opsicle/monitor/panels/deployments"
5
+ require "opsicle/monitor/panels/help"
6
+
7
+
8
+ describe Opsicle::Monitor::Screen do
9
+
10
+ before do
11
+
12
+ curses_test = double(
13
+ "Curses",
14
+ :init_screen => nil,
15
+ :close_screen => nil,
16
+ :nl => nil,
17
+ :noecho => nil,
18
+ :curs_set => nil,
19
+ :timeout= => nil,
20
+ :refresh => nil,
21
+ :lines => 24,
22
+ :cols => 80
23
+ )
24
+ stub_const "Curses", curses_test
25
+
26
+ @panel = double(
27
+ "@panel",
28
+ :close => nil,
29
+ :panel_main= => nil
30
+ )
31
+ @panel_d = @panel.dup
32
+ @panel_q = @panel.dup
33
+
34
+ allow(Opsicle::Monitor::Panels::Header).to receive(:new).and_return(@panel)
35
+ allow(Opsicle::Monitor::Panels::Deployments).to receive(:new).and_return(@panel_d)
36
+ allow(Opsicle::Monitor::Panels::Help).to receive(:new).and_return(@panel_h)
37
+
38
+ @screen = Opsicle::Monitor::Screen.new
39
+ end
40
+
41
+ describe "#initialize" do
42
+ it "inits screen" do
43
+ expect(Curses).to receive(:init_screen)
44
+
45
+ Opsicle::Monitor::Screen.new
46
+ end
47
+
48
+ it "sets height" do
49
+ expect(@screen.height).to equal(24)
50
+ end
51
+
52
+ it "sets width" do
53
+ expect(@screen.width).to equal(80)
54
+ end
55
+ end
56
+
57
+ describe "#close" do
58
+ it "closes screen" do
59
+ @screen.instance_variable_set(:@panels, { :panel => @panel })
60
+ expect(Curses).to receive(:close_screen)
61
+
62
+ @screen.close
63
+ end
64
+
65
+ it "closes panels" do
66
+ @panel2 = double
67
+ expect(@panel2).to receive(:close)
68
+
69
+ @screen.instance_variable_set(:@panels, { :panel2 => @panel2 })
70
+
71
+ @screen.close
72
+ end
73
+ end
74
+
75
+ describe "#refresh" do
76
+ it "refreshes panels" do
77
+ @panel2 = double
78
+ expect(@panel2).to receive(:refresh)
79
+
80
+ @screen.instance_variable_set(:@panels, { :panel2 => @panel2 })
81
+
82
+ @screen.refresh
83
+ end
84
+ end
85
+
86
+ describe "#next_key" do
87
+ it "gets next key" do
88
+ expect(Curses).to receive(:getch)
89
+
90
+ @screen.next_key
91
+ end
92
+ end
93
+
94
+ describe "#missized?" do
95
+ it "returns false when not missized" do
96
+ expect(@screen).to receive(:term_height).and_return(24)
97
+ expect(@screen).to receive(:term_width).and_return(80)
98
+
99
+ expect(@screen.missized?).to equal(false)
100
+
101
+ end
102
+
103
+ it "returns true when missized" do
104
+ expect(@screen).to receive(:term_height).and_return(21)
105
+ # Width isn't checked before height
106
+
107
+ expect(@screen.missized?).to equal(true)
108
+ end
109
+ end
110
+
111
+ describe "#panel_main=" do
112
+ before do
113
+ @panels = @screen.instance_variable_get(:@panels)
114
+ end
115
+
116
+ it "defaults panel_main to deployments" do
117
+ expect(@panels[:main]).to equal(@panel_d)
118
+ end
119
+ end
120
+
121
+ end
@@ -0,0 +1,41 @@
1
+ require 'spec_helper'
2
+ require 'opsicle/deployments'
3
+ require 'opsicle/monitor/spy/dataspyable'
4
+ require 'opsicle/monitor/translatable'
5
+ require 'opsicle/monitor/spy/deployments'
6
+ require 'opsicle/monitor/app'
7
+
8
+ describe Opsicle::Monitor::Spy::Deployments do
9
+ before do
10
+ @deployments = double(:data => {})
11
+
12
+ expect(Opsicle::Deployments).to receive(:new).and_return(@deployments)
13
+
14
+ @subject = Opsicle::Monitor::Spy::Deployments.new
15
+ end
16
+
17
+ describe "#user_from_arn" do
18
+ it "parses a normal user string" do
19
+ result = @subject.user_from_arn("arn:aws:iam::465198754621:user/chris.arcand")
20
+ expect(result).to eq("chris.arcand")
21
+ end
22
+
23
+ it "parses a root user string" do
24
+ result = @subject.user_from_arn("arn:aws:iam::465198754621:root")
25
+ expect(result).to eq("root")
26
+ end
27
+
28
+ it "handles an unknown string gracefully" do
29
+ result = @subject.user_from_arn("Ugly string")
30
+ expect(result).to eq("Ugly string")
31
+ end
32
+
33
+ it "handles a nil or empty string gracefully" do
34
+ nilstring = @subject.user_from_arn(nil)
35
+ emptystring = @subject.user_from_arn("")
36
+
37
+ expect(nilstring).to eq("")
38
+ expect(nilstring).to eq("")
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,199 @@
1
+ require "spec_helper"
2
+ require "opsicle/monitor/subpanel"
3
+
4
+
5
+ describe Opsicle::Monitor::Subpanel do
6
+
7
+ describe "#initialize" do
8
+ describe "required" do
9
+ before do
10
+ @window = double
11
+
12
+ @subpanel = Opsicle::Monitor::Subpanel.new(@window, 24, 80, 1, 2)
13
+ end
14
+
15
+ it "sets window" do
16
+ expect(@subpanel.instance_variable_get(:@window)).to equal(@window)
17
+ end
18
+
19
+ it "sets height" do
20
+ expect(@subpanel.height).to equal(24)
21
+ end
22
+
23
+ it "sets width" do
24
+ expect(@subpanel.width).to equal(80)
25
+ end
26
+
27
+ it "sets top" do
28
+ expect(@subpanel.top).to equal(1)
29
+ end
30
+
31
+ it "sets left" do
32
+ expect(@subpanel.left).to equal(2)
33
+ end
34
+
35
+ it "defaults data" do
36
+
37
+ expect(@subpanel.data).to eq({
38
+ :left => '',
39
+ :right => '',
40
+ })
41
+ end
42
+
43
+ it "defaults dividers" do
44
+ expect(@subpanel.dividers).to eq({
45
+ :left => '',
46
+ :right => '',
47
+ })
48
+ end
49
+
50
+ it "calculates content_width" do
51
+ expect(@subpanel.content_width).to equal(80)
52
+ end
53
+ end
54
+
55
+ describe "optional" do
56
+ before do
57
+ @subpanel = Opsicle::Monitor::Subpanel.new(double, 24, 80, 1, 2, {
58
+ :data_l => 'key:',
59
+ :data_r => 'value',
60
+ :divider_l => '<',
61
+ :divider_r => '/>',
62
+ })
63
+ end
64
+
65
+ it "sets data" do
66
+ expect(@subpanel.data).to eq({
67
+ :left => 'key:',
68
+ :right => 'value',
69
+ })
70
+ end
71
+
72
+ it "sets dividers" do
73
+ expect(@subpanel.dividers).to eq({
74
+ :left => '<',
75
+ :right => '/>',
76
+ })
77
+ end
78
+
79
+ it "calculates content_width" do
80
+ expect(@subpanel.content_width).to equal(77)
81
+ end
82
+ end
83
+ end
84
+
85
+ describe "#refresh" do
86
+ describe "strings and dividers" do
87
+ before do
88
+ @window = double
89
+
90
+ @subpanel = Opsicle::Monitor::Subpanel.new(@window, 24, 80, 1, 2, {
91
+ :data_l => 'key:',
92
+ :data_r => 'value',
93
+ :divider_l => '<-',
94
+ :divider_r => '|',
95
+ })
96
+ end
97
+
98
+ describe "when changed" do
99
+ it "sets position" do
100
+ allow(@window).to receive(:addstr)
101
+
102
+ expect(@window).to receive(:setpos).with(1, 2)
103
+
104
+ @subpanel.refresh
105
+ end
106
+
107
+ it "sets data" do
108
+ allow(@window).to receive(:setpos)
109
+
110
+ expect(@window).to receive(:addstr).with("<-key: value|")
111
+
112
+ @subpanel.refresh
113
+ end
114
+
115
+ it "sets truncated data when too long" do
116
+ @subpanel = Opsicle::Monitor::Subpanel.new(@window, 24, 10, 1, 2, {
117
+ :data_l => 'key:',
118
+ :data_r => 'value',
119
+ :divider_l => '<-',
120
+ :divider_r => '|',
121
+ })
122
+
123
+ allow(@window).to receive(:setpos)
124
+
125
+ expect(@window).to receive(:addstr).with("<-key:val|")
126
+
127
+ @subpanel.refresh
128
+ end
129
+ end
130
+
131
+ describe "when unchanged" do
132
+ before do
133
+ allow(@window).to receive(:setpos)
134
+ allow(@window).to receive(:addstr)
135
+
136
+ @subpanel.refresh
137
+ end
138
+
139
+ it "skips position" do
140
+ expect(@window).not_to receive(:setpos)
141
+
142
+ @subpanel.refresh
143
+ end
144
+
145
+ it "skips data" do
146
+ expect(@window).not_to receive(:addstr)
147
+
148
+ @subpanel.refresh
149
+ end
150
+ end
151
+ end
152
+
153
+ describe "lambdas" do
154
+ before do
155
+ @window = double
156
+
157
+ @subpanel = Opsicle::Monitor::Subpanel.new(@window, 24, 80, 0, 0, {
158
+ :data_l => -> { "the answer:" },
159
+ :data_r => -> { "42" }
160
+ })
161
+ end
162
+
163
+ it "sets data when changed" do
164
+ allow(@window).to receive(:setpos)
165
+
166
+ expect(@window).to receive(:addstr).with("the answer: 42")
167
+
168
+ @subpanel.refresh
169
+ end
170
+
171
+ it "sets data when non-string" do
172
+ @subpanel = Opsicle::Monitor::Subpanel.new(@window, 24, 10, 0, 0, {
173
+ :data_l => -> { 2 * 3 * 7 },
174
+ :data_r => -> { 42 }
175
+ })
176
+
177
+ allow(@window).to receive(:setpos)
178
+
179
+ expect(@window).to receive(:addstr).with("42 42")
180
+
181
+ @subpanel.refresh
182
+ end
183
+
184
+ it "sets empty data when nil" do
185
+ @subpanel = Opsicle::Monitor::Subpanel.new(@window, 24, 10, 0, 0, {
186
+ :data_l => -> { nil },
187
+ :data_r => -> { nil }
188
+ })
189
+
190
+ allow(@window).to receive(:setpos)
191
+
192
+ expect(@window).to receive(:addstr).with(" ")
193
+
194
+ @subpanel.refresh
195
+ end
196
+ end
197
+ end
198
+
199
+ end