azuki 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (99) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +71 -0
  3. data/bin/azuki +17 -0
  4. data/data/cacert.pem +3988 -0
  5. data/lib/azuki.rb +17 -0
  6. data/lib/azuki/auth.rb +339 -0
  7. data/lib/azuki/cli.rb +38 -0
  8. data/lib/azuki/client.rb +764 -0
  9. data/lib/azuki/client/azuki_postgresql.rb +141 -0
  10. data/lib/azuki/client/cisaurus.rb +26 -0
  11. data/lib/azuki/client/pgbackups.rb +113 -0
  12. data/lib/azuki/client/rendezvous.rb +108 -0
  13. data/lib/azuki/client/ssl_endpoint.rb +25 -0
  14. data/lib/azuki/command.rb +294 -0
  15. data/lib/azuki/command/account.rb +23 -0
  16. data/lib/azuki/command/accounts.rb +34 -0
  17. data/lib/azuki/command/addons.rb +305 -0
  18. data/lib/azuki/command/apps.rb +393 -0
  19. data/lib/azuki/command/auth.rb +86 -0
  20. data/lib/azuki/command/base.rb +230 -0
  21. data/lib/azuki/command/certs.rb +209 -0
  22. data/lib/azuki/command/config.rb +137 -0
  23. data/lib/azuki/command/db.rb +218 -0
  24. data/lib/azuki/command/domains.rb +85 -0
  25. data/lib/azuki/command/drains.rb +46 -0
  26. data/lib/azuki/command/fork.rb +164 -0
  27. data/lib/azuki/command/git.rb +64 -0
  28. data/lib/azuki/command/help.rb +179 -0
  29. data/lib/azuki/command/keys.rb +115 -0
  30. data/lib/azuki/command/labs.rb +147 -0
  31. data/lib/azuki/command/logs.rb +45 -0
  32. data/lib/azuki/command/maintenance.rb +61 -0
  33. data/lib/azuki/command/pg.rb +269 -0
  34. data/lib/azuki/command/pgbackups.rb +329 -0
  35. data/lib/azuki/command/plugins.rb +110 -0
  36. data/lib/azuki/command/ps.rb +232 -0
  37. data/lib/azuki/command/regions.rb +22 -0
  38. data/lib/azuki/command/releases.rb +124 -0
  39. data/lib/azuki/command/run.rb +180 -0
  40. data/lib/azuki/command/sharing.rb +89 -0
  41. data/lib/azuki/command/ssl.rb +43 -0
  42. data/lib/azuki/command/stack.rb +62 -0
  43. data/lib/azuki/command/status.rb +51 -0
  44. data/lib/azuki/command/update.rb +47 -0
  45. data/lib/azuki/command/version.rb +23 -0
  46. data/lib/azuki/deprecated.rb +5 -0
  47. data/lib/azuki/deprecated/help.rb +38 -0
  48. data/lib/azuki/distribution.rb +9 -0
  49. data/lib/azuki/excon.rb +9 -0
  50. data/lib/azuki/helpers.rb +517 -0
  51. data/lib/azuki/helpers/azuki_postgresql.rb +165 -0
  52. data/lib/azuki/helpers/log_displayer.rb +70 -0
  53. data/lib/azuki/plugin.rb +163 -0
  54. data/lib/azuki/updater.rb +171 -0
  55. data/lib/azuki/version.rb +3 -0
  56. data/lib/vendor/azuki/okjson.rb +598 -0
  57. data/spec/azuki/auth_spec.rb +256 -0
  58. data/spec/azuki/client/azuki_postgresql_spec.rb +71 -0
  59. data/spec/azuki/client/pgbackups_spec.rb +43 -0
  60. data/spec/azuki/client/rendezvous_spec.rb +62 -0
  61. data/spec/azuki/client/ssl_endpoint_spec.rb +48 -0
  62. data/spec/azuki/client_spec.rb +564 -0
  63. data/spec/azuki/command/addons_spec.rb +601 -0
  64. data/spec/azuki/command/apps_spec.rb +351 -0
  65. data/spec/azuki/command/auth_spec.rb +38 -0
  66. data/spec/azuki/command/base_spec.rb +109 -0
  67. data/spec/azuki/command/certs_spec.rb +178 -0
  68. data/spec/azuki/command/config_spec.rb +144 -0
  69. data/spec/azuki/command/db_spec.rb +110 -0
  70. data/spec/azuki/command/domains_spec.rb +87 -0
  71. data/spec/azuki/command/drains_spec.rb +34 -0
  72. data/spec/azuki/command/fork_spec.rb +56 -0
  73. data/spec/azuki/command/git_spec.rb +144 -0
  74. data/spec/azuki/command/help_spec.rb +93 -0
  75. data/spec/azuki/command/keys_spec.rb +120 -0
  76. data/spec/azuki/command/labs_spec.rb +100 -0
  77. data/spec/azuki/command/logs_spec.rb +60 -0
  78. data/spec/azuki/command/maintenance_spec.rb +51 -0
  79. data/spec/azuki/command/pg_spec.rb +236 -0
  80. data/spec/azuki/command/pgbackups_spec.rb +307 -0
  81. data/spec/azuki/command/plugins_spec.rb +104 -0
  82. data/spec/azuki/command/ps_spec.rb +195 -0
  83. data/spec/azuki/command/releases_spec.rb +130 -0
  84. data/spec/azuki/command/run_spec.rb +83 -0
  85. data/spec/azuki/command/sharing_spec.rb +59 -0
  86. data/spec/azuki/command/stack_spec.rb +46 -0
  87. data/spec/azuki/command/status_spec.rb +48 -0
  88. data/spec/azuki/command/version_spec.rb +16 -0
  89. data/spec/azuki/command_spec.rb +211 -0
  90. data/spec/azuki/helpers/azuki_postgresql_spec.rb +155 -0
  91. data/spec/azuki/helpers_spec.rb +48 -0
  92. data/spec/azuki/plugin_spec.rb +172 -0
  93. data/spec/azuki/updater_spec.rb +44 -0
  94. data/spec/helper/legacy_help.rb +16 -0
  95. data/spec/spec.opts +1 -0
  96. data/spec/spec_helper.rb +224 -0
  97. data/spec/support/display_message_matcher.rb +49 -0
  98. data/spec/support/openssl_mock_helper.rb +8 -0
  99. metadata +211 -0
@@ -0,0 +1,34 @@
1
+ require "spec_helper"
2
+ require "azuki/command/drains"
3
+
4
+ describe Azuki::Command::Drains do
5
+
6
+ describe "drains" do
7
+ it "can list drains" do
8
+ stub_core.list_drains("example").returns("drains")
9
+ stderr, stdout = execute("drains")
10
+ stderr.should == ""
11
+ stdout.should == <<-STDOUT
12
+ drains
13
+ STDOUT
14
+ end
15
+
16
+ it "can add drains" do
17
+ stub_core.add_drain("example", "syslog://localhost/add").returns("added")
18
+ stderr, stdout = execute("drains:add syslog://localhost/add")
19
+ stderr.should == ""
20
+ stdout.should == <<-STDOUT
21
+ added
22
+ STDOUT
23
+ end
24
+
25
+ it "can remove drains" do
26
+ stub_core.remove_drain("example", "syslog://localhost/remove").returns("removed")
27
+ stderr, stdout = execute("drains:remove syslog://localhost/remove")
28
+ stderr.should == ""
29
+ stdout.should == <<-STDOUT
30
+ removed
31
+ STDOUT
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,56 @@
1
+ require "spec_helper"
2
+ require "azuki/command/fork"
3
+ require "azuki/client/cisaurus"
4
+
5
+ module Azuki::Command
6
+
7
+ describe Fork do
8
+
9
+ before(:each) do
10
+ stub_core
11
+ api.post_app("name" => "example", "stack" => "cedar")
12
+ end
13
+
14
+ after(:each) do
15
+ api.delete_app("example")
16
+ api.delete_app("example-fork")
17
+ end
18
+
19
+ context "successfully" do
20
+
21
+ before(:each) do
22
+ stub_cisaurus.copy_slug.returns("/v1/jobs/4099d263-bf67-4c0b-80f5-64a5d25598fd")
23
+ stub_cisaurus.job_done?.returns(true)
24
+ end
25
+
26
+ it "forks an app" do
27
+ stderr, stdout = execute("fork example-fork")
28
+ stderr.should == ""
29
+ stdout.should == <<-STDOUT
30
+ Creating fork example-fork... done
31
+ Copying slug... done
32
+ Copying config vars... done
33
+ Fork complete, view it at http://example-fork.azukiapp.com/
34
+ STDOUT
35
+ end
36
+
37
+ it "copies config vars" do
38
+ config_vars = {
39
+ "SECRET" => "imasecret",
40
+ "FOO" => "bar",
41
+ "LANG_ENV" => "production"
42
+ }
43
+ api.put_config_vars("example", config_vars)
44
+ execute("fork example-fork")
45
+ api.get_config_vars("example-fork").body.should == config_vars
46
+ end
47
+
48
+ it "re-provisions add-ons" do
49
+ addons = ["pgbackups:basic", "deployhooks:http"].sort
50
+ addons.each { |a| api.post_addon("example", a) }
51
+ execute("fork example-fork")
52
+ api.get_addons("example-fork").body.collect { |info| info["name"] }.sort.should == addons
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,144 @@
1
+ require 'spec_helper'
2
+ require 'azuki/command/git'
3
+
4
+ module Azuki::Command
5
+ describe Git do
6
+
7
+ before(:each) do
8
+ stub_core
9
+ end
10
+
11
+ context("clone") do
12
+
13
+ before(:each) do
14
+ api.post_app("name" => "example", "stack" => "cedar")
15
+ end
16
+
17
+ after(:each) do
18
+ api.delete_app("example")
19
+ end
20
+
21
+ it "clones and adds remote" do
22
+ any_instance_of(Azuki::Command::Git) do |git|
23
+ mock(git).system("git clone -o azuki git@azukiapp.com:example.git") do
24
+ puts "Cloning into 'example'..."
25
+ end
26
+ end
27
+ stderr, stdout = execute("git:clone example")
28
+ stderr.should == ""
29
+ stdout.should == <<-STDOUT
30
+ Cloning from app 'example'...
31
+ Cloning into 'example'...
32
+ STDOUT
33
+ end
34
+
35
+ it "clones into another dir" do
36
+ any_instance_of(Azuki::Command::Git) do |git|
37
+ mock(git).system("git clone -o azuki git@azukiapp.com:example.git somedir") do
38
+ puts "Cloning into 'somedir'..."
39
+ end
40
+ end
41
+ stderr, stdout = execute("git:clone example somedir")
42
+ stderr.should == ""
43
+ stdout.should == <<-STDOUT
44
+ Cloning from app 'example'...
45
+ Cloning into 'somedir'...
46
+ STDOUT
47
+ end
48
+
49
+ it "can specify app with -a" do
50
+ any_instance_of(Azuki::Command::Git) do |git|
51
+ mock(git).system("git clone -o azuki git@azukiapp.com:example.git") do
52
+ puts "Cloning into 'example'..."
53
+ end
54
+ end
55
+ stderr, stdout = execute("git:clone -a example")
56
+ stderr.should == ""
57
+ stdout.should == <<-STDOUT
58
+ Cloning from app 'example'...
59
+ Cloning into 'example'...
60
+ STDOUT
61
+ end
62
+
63
+ it "can specify app with -a and a dir" do
64
+ any_instance_of(Azuki::Command::Git) do |git|
65
+ mock(git).system("git clone -o azuki git@azukiapp.com:example.git somedir") do
66
+ puts "Cloning into 'somedir'..."
67
+ end
68
+ end
69
+ stderr, stdout = execute("git:clone -a example somedir")
70
+ stderr.should == ""
71
+ stdout.should == <<-STDOUT
72
+ Cloning from app 'example'...
73
+ Cloning into 'somedir'...
74
+ STDOUT
75
+ end
76
+
77
+ it "clones and sets -r remote" do
78
+ any_instance_of(Azuki::Command::Git) do |git|
79
+ mock(git).system("git clone -o other git@azukiapp.com:example.git") do
80
+ puts "Cloning into 'example'..."
81
+ end
82
+ end
83
+ stderr, stdout = execute("git:clone example -r other")
84
+ stderr.should == ""
85
+ stdout.should == <<-STDOUT
86
+ Cloning from app 'example'...
87
+ Cloning into 'example'...
88
+ STDOUT
89
+ end
90
+
91
+ end
92
+
93
+ context("remote") do
94
+
95
+ before(:each) do
96
+ api.post_app("name" => "example", "stack" => "cedar")
97
+ FileUtils.mkdir('example')
98
+ FileUtils.chdir('example') { `git init` }
99
+ end
100
+
101
+ after(:each) do
102
+ api.delete_app("example")
103
+ FileUtils.rm_rf('example')
104
+ end
105
+
106
+ it "adds remote" do
107
+ any_instance_of(Azuki::Command::Git) do |git|
108
+ stub(git).git('remote').returns("origin")
109
+ stub(git).git('remote add azuki git@azukiapp.com:example.git')
110
+ end
111
+ stderr, stdout = execute("git:remote")
112
+ stderr.should == ""
113
+ stdout.should == <<-STDOUT
114
+ Git remote azuki added
115
+ STDOUT
116
+ end
117
+
118
+ it "adds -r remote" do
119
+ any_instance_of(Azuki::Command::Git) do |git|
120
+ stub(git).git('remote').returns("origin")
121
+ stub(git).git('remote add other git@azukiapp.com:example.git')
122
+ end
123
+ stderr, stdout = execute("git:remote -r other")
124
+ stderr.should == ""
125
+ stdout.should == <<-STDOUT
126
+ Git remote other added
127
+ STDOUT
128
+ end
129
+
130
+ it "skips remote when it already exists" do
131
+ any_instance_of(Azuki::Command::Git) do |git|
132
+ stub(git).git('remote').returns("azuki")
133
+ end
134
+ stderr, stdout = execute("git:remote")
135
+ stderr.should == <<-STDERR
136
+ ! Git remote azuki already exists
137
+ STDERR
138
+ stdout.should == ""
139
+ end
140
+
141
+ end
142
+
143
+ end
144
+ end
@@ -0,0 +1,93 @@
1
+ require "spec_helper"
2
+ require "azuki/command/apps"
3
+ require "azuki/command/help"
4
+
5
+ describe Azuki::Command::Help do
6
+
7
+ describe "help" do
8
+ it "should show root help with no args" do
9
+ stderr, stdout = execute("help")
10
+ stderr.should == ""
11
+ stdout.should include "Usage: azuki COMMAND [--app APP] [command-specific-options]"
12
+ stdout.should include "apps"
13
+ stdout.should include "help"
14
+ end
15
+
16
+ it "should show command help and namespace help when ambigious" do
17
+ stderr, stdout = execute("help apps")
18
+ stderr.should == ""
19
+ stdout.should include "azuki apps"
20
+ stdout.should include "list your apps"
21
+ stdout.should include "Additional commands"
22
+ stdout.should include "apps:create"
23
+ end
24
+
25
+ it "should show only command help when not ambiguous" do
26
+ stderr, stdout = execute("help apps:create")
27
+ stderr.should == ""
28
+ stdout.should include "azuki apps:create"
29
+ stdout.should include "create a new app"
30
+ stdout.should_not include "Additional commands"
31
+ end
32
+
33
+ it "should show command help with --help" do
34
+ stderr, stdout = execute("apps:create --help")
35
+ stderr.should == ""
36
+ stdout.should include "Usage: azuki apps:create"
37
+ stdout.should include "create a new app"
38
+ stdout.should_not include "Additional commands"
39
+ end
40
+
41
+ it "should redirect if the command is an alias" do
42
+ stderr, stdout = execute("help create")
43
+ stderr.should == ""
44
+ stdout.should include "Alias: create redirects to apps:create"
45
+ stdout.should include "Usage: azuki apps:create"
46
+ stdout.should include "create a new app"
47
+ stdout.should_not include "Additional commands"
48
+ end
49
+
50
+ it "should show if the command does not exist" do
51
+ stderr, stdout = execute("help sudo:sandwich")
52
+ stderr.should == <<-STDERR
53
+ ! sudo:sandwich is not a azuki command. See `azuki help`.
54
+ STDERR
55
+ stdout.should == ""
56
+ end
57
+
58
+ it "should show help with naked -h" do
59
+ stderr, stdout = execute("-h")
60
+ stderr.should == ""
61
+ stdout.should include "Usage: azuki COMMAND"
62
+ end
63
+
64
+ it "should show help with naked --help" do
65
+ stderr, stdout = execute("--help")
66
+ stderr.should == ""
67
+ stdout.should include "Usage: azuki COMMAND"
68
+ end
69
+
70
+ describe "with legacy help" do
71
+ require "helper/legacy_help"
72
+
73
+ it "displays the legacy group in the namespace list" do
74
+ stderr, stdout = execute("help")
75
+ stderr.should == ""
76
+ stdout.should include "Foo Group"
77
+ end
78
+
79
+ it "displays group help" do
80
+ stderr, stdout = execute("help foo")
81
+ stderr.should == ""
82
+ stdout.should include "do a bar to foo"
83
+ stdout.should include "do a baz to foo"
84
+ end
85
+
86
+ it "displays legacy command-specific help" do
87
+ stderr, stdout = execute("help foo:bar")
88
+ stderr.should == ""
89
+ stdout.should include "do a bar to foo"
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,120 @@
1
+ require "spec_helper"
2
+ require "azuki/command/keys"
3
+
4
+ module Azuki::Command
5
+ describe Keys do
6
+ KEY = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp9AJD5QABmOcrkHm6SINuQkDefaR0MUrfgZ1Pxir3a4fM1fwa00dsUwbUaRuR7FEFD8n1E9WwDf8SwQTHtyZsJg09G9myNqUzkYXCmydN7oGr5IdVhRyv5ixcdiE0hj7dRnOJg2poSQ3Qi+Ka8SVJzF7nIw1YhuicHPSbNIFKi5s0D5a+nZb/E6MNGvhxoFCQX2IcNxaJMqhzy1ESwlixz45aT72mXYq0LIxTTpoTqma1HuKdRY8HxoREiivjmMQulYP+CxXFcMyV9kxTKIUZ/FXqlC6G5vSm3J4YScSatPOj9ID5HowpdlIx8F6y4p1/28r2tTl4CY40FFyoke4MQ== pedro@azuki"
7
+
8
+ before(:each) do
9
+ stub_core
10
+ end
11
+
12
+ context("add") do
13
+
14
+ after(:each) do
15
+ api.delete_key("pedro@azuki")
16
+ end
17
+
18
+ it "tries to find a key if no key filename is supplied" do
19
+ Azuki::Auth.should_receive(:ask).and_return("y")
20
+ Azuki::Auth.should_receive(:generate_ssh_key)
21
+ File.should_receive(:exists?).with('.git').and_return(false)
22
+ File.should_receive(:exists?).with('/.ssh/id_rsa.pub').and_return(true)
23
+ File.should_receive(:read).with('/.ssh/id_rsa.pub').and_return(KEY)
24
+ stderr, stdout = execute("keys:add")
25
+ stderr.should == ""
26
+ stdout.should == <<-STDOUT
27
+ Could not find an existing public key.
28
+ Would you like to generate one? [Yn] Generating new SSH public key.
29
+ Uploading SSH public key /.ssh/id_rsa.pub... done
30
+ STDOUT
31
+ end
32
+
33
+ it "adds a key from a specified keyfile path" do
34
+ File.should_receive(:exists?).with('.git').and_return(false)
35
+ File.should_receive(:exists?).with('/my/key.pub').and_return(true)
36
+ File.should_receive(:read).with('/my/key.pub').and_return(KEY)
37
+ stderr, stdout = execute("keys:add /my/key.pub")
38
+ stderr.should == ""
39
+ stdout.should == <<-STDOUT
40
+ Uploading SSH public key /my/key.pub... done
41
+ STDOUT
42
+ end
43
+
44
+ end
45
+
46
+ context("index") do
47
+
48
+ before do
49
+ api.post_key(KEY)
50
+ end
51
+
52
+ after do
53
+ api.delete_key("pedro@azuki")
54
+ end
55
+
56
+ it "list keys, trimming the hex code for better display" do
57
+ stderr, stdout = execute("keys")
58
+ stderr.should == ""
59
+ stdout.should == <<-STDOUT
60
+ === email@example.com Keys
61
+ ssh-rsa AAAAB3NzaC...Fyoke4MQ== pedro@azuki
62
+
63
+ STDOUT
64
+ end
65
+
66
+ it "list keys showing the whole key hex with --long" do
67
+ stderr, stdout = execute("keys --long")
68
+ stderr.should == ""
69
+ stdout.should == <<-STDOUT
70
+ === email@example.com Keys
71
+ ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAp9AJD5QABmOcrkHm6SINuQkDefaR0MUrfgZ1Pxir3a4fM1fwa00dsUwbUaRuR7FEFD8n1E9WwDf8SwQTHtyZsJg09G9myNqUzkYXCmydN7oGr5IdVhRyv5ixcdiE0hj7dRnOJg2poSQ3Qi+Ka8SVJzF7nIw1YhuicHPSbNIFKi5s0D5a+nZb/E6MNGvhxoFCQX2IcNxaJMqhzy1ESwlixz45aT72mXYq0LIxTTpoTqma1HuKdRY8HxoREiivjmMQulYP+CxXFcMyV9kxTKIUZ/FXqlC6G5vSm3J4YScSatPOj9ID5HowpdlIx8F6y4p1/28r2tTl4CY40FFyoke4MQ== pedro@azuki
72
+
73
+ STDOUT
74
+ end
75
+
76
+ end
77
+
78
+ context("remove") do
79
+
80
+ context("success") do
81
+
82
+ before(:each) do
83
+ api.post_key(KEY)
84
+ end
85
+
86
+ it "succeeds" do
87
+ stderr, stdout = execute("keys:remove pedro@azuki")
88
+ stderr.should == ""
89
+ stdout.should == <<-STDOUT
90
+ Removing pedro@azuki SSH key... done
91
+ STDOUT
92
+ end
93
+
94
+ end
95
+
96
+ it "displays an error if no key is specified" do
97
+ stderr, stdout = execute("keys:remove")
98
+ stderr.should == <<-STDERR
99
+ ! Usage: azuki keys:remove KEY
100
+ ! Must specify KEY to remove.
101
+ STDERR
102
+ stdout.should == ""
103
+ end
104
+
105
+ end
106
+
107
+ context("clear") do
108
+
109
+ it "succeeds" do
110
+ stderr, stdout = execute("keys:clear")
111
+ stderr.should == ""
112
+ stdout.should == <<-STDOUT
113
+ Removing all SSH keys... done
114
+ STDOUT
115
+ end
116
+
117
+ end
118
+
119
+ end
120
+ end