azuki 0.0.1

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.
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