c66 0.1.0 → 0.1.8
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of c66 might be problematic. Click here for more details.
- data/.gitignore +10 -5
- data/Gemfile.lock +42 -0
- data/README.md +107 -48
- data/lib/c66/commands/c66_toolbelt.rb +175 -59
- data/lib/c66/utils/version.rb +1 -1
- data/toolbelt.go +125 -0
- metadata +109 -61
- /data/bin/{c66.rb → c66} +0 -0
data/.gitignore
CHANGED
@@ -2,12 +2,8 @@
|
|
2
2
|
*.rbc
|
3
3
|
.bundle
|
4
4
|
.config
|
5
|
-
.yardoc
|
6
|
-
Gemfile.lock
|
7
|
-
InstalledFiles
|
8
|
-
_yardoc
|
9
5
|
coverage
|
10
|
-
|
6
|
+
InstalledFiles
|
11
7
|
lib/bundler/man
|
12
8
|
pkg
|
13
9
|
rdoc
|
@@ -15,3 +11,12 @@ spec/reports
|
|
15
11
|
test/tmp
|
16
12
|
test/version_tmp
|
17
13
|
tmp
|
14
|
+
.cloud66
|
15
|
+
|
16
|
+
# YARD artifacts
|
17
|
+
.yardoc
|
18
|
+
_yardoc
|
19
|
+
doc/
|
20
|
+
|
21
|
+
.ruby-gemset
|
22
|
+
.ruby-version
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
c66 (0.1.6)
|
5
|
+
bundler (~> 1.3)
|
6
|
+
httparty (~> 0.11.0)
|
7
|
+
json (~> 1.7.7)
|
8
|
+
oauth2 (~> 0.9.2)
|
9
|
+
rake (~> 10.1.0)
|
10
|
+
thor (~> 0.18.1)
|
11
|
+
|
12
|
+
GEM
|
13
|
+
remote: https://rubygems.org/
|
14
|
+
specs:
|
15
|
+
faraday (0.8.7)
|
16
|
+
multipart-post (~> 1.1)
|
17
|
+
httparty (0.11.0)
|
18
|
+
multi_json (~> 1.0)
|
19
|
+
multi_xml (>= 0.5.2)
|
20
|
+
httpauth (0.2.0)
|
21
|
+
json (1.7.7)
|
22
|
+
jwt (0.1.8)
|
23
|
+
multi_json (>= 1.5)
|
24
|
+
multi_json (1.7.7)
|
25
|
+
multi_xml (0.5.4)
|
26
|
+
multipart-post (1.2.0)
|
27
|
+
oauth2 (0.9.2)
|
28
|
+
faraday (~> 0.8)
|
29
|
+
httpauth (~> 0.2)
|
30
|
+
jwt (~> 0.1.4)
|
31
|
+
multi_json (~> 1.0)
|
32
|
+
multi_xml (~> 0.5)
|
33
|
+
rack (~> 1.2)
|
34
|
+
rack (1.5.2)
|
35
|
+
rake (10.1.0)
|
36
|
+
thor (0.18.1)
|
37
|
+
|
38
|
+
PLATFORMS
|
39
|
+
ruby
|
40
|
+
|
41
|
+
DEPENDENCIES
|
42
|
+
c66!
|
data/README.md
CHANGED
@@ -1,65 +1,111 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
Cloud 66 Toolbelt is a simple command-line tool for the awesome Cloud 66 customers. It allows you to deploy, modify settings and retrieve the current status of your Cloud 66 stacks, and much more!
|
1
|
+
<h1 class="doc-title">Cloud 66 Toolbelt</h1>
|
2
|
+
<p class="lead">Cloud 66 Toolbelt is a simple command-line tool for the awesome Cloud 66 customers. It allows you to deploy, modify settings and retrieve the current status of your Cloud 66 stacks, and much more!</p>
|
4
3
|
|
5
4
|
## Installation
|
6
5
|
|
7
6
|
You can install the Cloud 66 Toolbelt using [RubyGems](http://rubygems.org/):
|
8
|
-
|
9
|
-
|
7
|
+
<p>
|
8
|
+
<kbd>$ gem install c66</kbd>
|
9
|
+
</p>
|
10
10
|
|
11
11
|
## Usage
|
12
12
|
|
13
13
|
### Help
|
14
|
+
|
14
15
|
With c66 installed, you can display the help with one of the following instructions:
|
16
|
+
<p>
|
17
|
+
<kbd>$ c66 help</kbd>
|
18
|
+
</p>
|
19
|
+
|
20
|
+
or
|
15
21
|
|
16
|
-
|
22
|
+
<p>
|
23
|
+
<kbd>$ c66</kbd>
|
24
|
+
</p>
|
17
25
|
|
18
|
-
or
|
26
|
+
or for a specific command:
|
19
27
|
|
20
|
-
|
28
|
+
<p>
|
29
|
+
<kbd>$ c66 help <command></kbd>
|
30
|
+
</p>
|
21
31
|
|
22
32
|
### Initialize the Toolbelt
|
23
33
|
|
24
34
|
Firstly, to use the Toolbelt, you will need to initiate it using:
|
25
35
|
|
26
|
-
|
27
|
-
|
36
|
+
<p>
|
37
|
+
<kbd>$ c66 init</kbd>
|
38
|
+
</p>
|
39
|
+
|
28
40
|
Then visit the URL given once authorized, copy and paste the `authorization code` into the command-line interface.
|
29
|
-
|
30
41
|
You need to sign in and allow the Cloud 66 Toolbelt application to use your account to access to the authorization code.
|
31
42
|
|
32
|
-
Note
|
43
|
+
**Note**: This is a one-off task.
|
33
44
|
|
34
45
|
### List the Stacks
|
35
46
|
|
36
47
|
You can list all your stacks using:
|
37
48
|
|
38
|
-
|
49
|
+
<p>
|
50
|
+
<kbd>$ c66 list</kbd>
|
51
|
+
</p>
|
39
52
|
|
40
53
|
### Deploy a Stack
|
41
54
|
|
42
55
|
Deploy a stack using the command `deploy` with a stack UID (Unique Identifer):
|
43
56
|
|
44
|
-
|
45
|
-
|
57
|
+
<p>
|
58
|
+
<kbd>$ c66 deploy --stack <stack_UID></kbd>
|
59
|
+
</p>
|
60
|
+
|
46
61
|
or
|
47
62
|
|
48
|
-
|
49
|
-
|
63
|
+
<p>
|
64
|
+
<kbd>$ c66 deploy -s <stack_UID></kbd>
|
65
|
+
</p>
|
66
|
+
|
50
67
|
You can retrieve the UID of a stack using the `list` command.
|
51
|
-
|
52
68
|
Through the Cloud 66 interface, click on your stack, then click on the cog and select the stack information view to retrieve the UID:
|
53
|
-
|
54
69
|
![stack_uid](http://cdn.cloud66.com.s3.amazonaws.com/images/Toolbelt/exemple_stack_uid.PNG)
|
55
70
|
|
56
|
-
|
71
|
+
There is a command to save a default stack UID:
|
72
|
+
|
73
|
+
<p>
|
74
|
+
<kbd>$ c66 save --stack <stack_UID></kbd>
|
75
|
+
</p>
|
76
|
+
|
77
|
+
or
|
78
|
+
|
79
|
+
<p>
|
80
|
+
<kbd>$ c66 save -s <stack_UID></kbd>
|
81
|
+
</p>
|
57
82
|
|
58
|
-
|
83
|
+
**Note:** The stack is saved in your current folder (.cloud66/stack.json) and only one default stack will be saved per folder.
|
59
84
|
|
85
|
+
When your stack UID is saved, you are able to use other commands without specify the stack UID.
|
86
|
+
For instance, it allows you to deploy a stack without putting the stack UID every time:
|
87
|
+
|
88
|
+
<p>
|
89
|
+
<kbd>$ c66 deploy</kbd>
|
90
|
+
</p>
|
91
|
+
|
60
92
|
you can use a short-cut for this command:
|
61
93
|
|
62
|
-
|
94
|
+
<p>
|
95
|
+
<kbd>$ c66 d</kbd>
|
96
|
+
</p>
|
97
|
+
|
98
|
+
You can save multiple stack UID by giving an alias to a specific stack:
|
99
|
+
|
100
|
+
<p>
|
101
|
+
<kbd>$ c66 save --stack <stack_UID> --alias <stack_alias></kbd>
|
102
|
+
</p>
|
103
|
+
|
104
|
+
Then you can use commands and specific a stack's alias, like so:
|
105
|
+
|
106
|
+
<p>
|
107
|
+
<kbd>$ c66 deploy -s <stack_alias></kbd>
|
108
|
+
</p>
|
63
109
|
|
64
110
|
### Settings of a Stack
|
65
111
|
|
@@ -67,45 +113,58 @@ It is possible to retrieve the settings of a specified stack and to easily modif
|
|
67
113
|
|
68
114
|
To display the settings:
|
69
115
|
|
70
|
-
|
71
|
-
|
116
|
+
<p>
|
117
|
+
<kbd>$ c66 settings --stack <stack_UID></kbd>
|
118
|
+
</p>
|
119
|
+
|
72
120
|
or
|
73
121
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
122
|
+
<p>
|
123
|
+
<kbd>$ c66 settings -s <stack_UID></kbd>
|
124
|
+
</p>
|
125
|
+
|
126
|
+
If a default stack UID is saved:
|
79
127
|
|
128
|
+
<p>
|
129
|
+
<kbd>$ c66 settings</kbd>
|
130
|
+
</p>
|
131
|
+
|
80
132
|
To modify a setting:
|
81
133
|
|
82
|
-
|
83
|
-
|
134
|
+
<p>
|
135
|
+
<kbd>$ c66 set --stack <stack_UID> --setting_name <setting_name> --value <value></kbd>
|
136
|
+
</p>
|
137
|
+
|
84
138
|
or
|
85
139
|
|
86
|
-
|
87
|
-
|
88
|
-
|
140
|
+
<p>
|
141
|
+
<kbd>$ c66 set -s <stack_UID> -n <setting_name> -v <value></kbd>
|
142
|
+
</p>
|
143
|
+
|
144
|
+
If a default stack UID is saved:
|
89
145
|
|
90
|
-
|
146
|
+
<p>
|
147
|
+
<kbd>$ c66 set --setting_name <setting_name> --value <value></kbd>
|
148
|
+
</p>
|
149
|
+
|
150
|
+
or
|
91
151
|
|
92
|
-
|
152
|
+
<p>
|
153
|
+
<kbd>$ c66 set -n <setting_name> -v <value></kbd>
|
154
|
+
</p>
|
93
155
|
|
94
|
-
|
156
|
+
### Information of your toolbelt settings
|
95
157
|
|
158
|
+
At any time, you can see your toolbelt settings, it includes the version of the toolbelt but also some information about your saved stacks:
|
159
|
+
|
160
|
+
<p>
|
161
|
+
<kbd>$ c66 info</kbd>
|
162
|
+
</p>
|
96
163
|
|
97
164
|
## Contributing
|
98
165
|
|
99
166
|
1. Fork it
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
104
|
-
|
105
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
106
|
-
|
167
|
+
2. Create your feature branch `git checkout -b my-new-feature`
|
168
|
+
3. Commit your changes `git commit -am 'Add some feature'`
|
169
|
+
4. Push to the branch `git push origin my-new-feature`
|
107
170
|
5. Create new Pull Request
|
108
|
-
|
109
|
-
## Copyright
|
110
|
-
|
111
|
-
Copyright (c) 2013 Cloud66 Limited.. See LICENSE for details.
|
@@ -8,6 +8,7 @@ module C66
|
|
8
8
|
module Commands
|
9
9
|
|
10
10
|
CLIENT_NAME = 'c66'
|
11
|
+
CLIENT_FULLNAME = 'Cloud 66 Toolbelt'
|
11
12
|
|
12
13
|
STK_QUEUED = 0
|
13
14
|
STK_SUCCESS = 1
|
@@ -47,6 +48,7 @@ module C66
|
|
47
48
|
end
|
48
49
|
|
49
50
|
def base_url
|
51
|
+
load_params
|
50
52
|
values[:base_url]
|
51
53
|
end
|
52
54
|
|
@@ -74,8 +76,16 @@ module C66
|
|
74
76
|
File.join(c66_path, "params.json")
|
75
77
|
end
|
76
78
|
|
77
|
-
def stack_file
|
78
|
-
|
79
|
+
def stack_file(alias_name = nil)
|
80
|
+
if alias_name
|
81
|
+
if alias_name.match(/\w/)
|
82
|
+
File.join(stack_path, "#{alias_name}.json")
|
83
|
+
else
|
84
|
+
abort "#{alias_name} is an invalid alias."
|
85
|
+
end
|
86
|
+
else
|
87
|
+
File.join(stack_path, "stack.json")
|
88
|
+
end
|
79
89
|
end
|
80
90
|
|
81
91
|
def load_config
|
@@ -88,7 +98,7 @@ module C66
|
|
88
98
|
|
89
99
|
def save_config
|
90
100
|
if !File.directory?(c66_path)
|
91
|
-
Dir.
|
101
|
+
Dir.mkdir(c66_path)
|
92
102
|
end
|
93
103
|
|
94
104
|
File.open(config_file,"w") do |f|
|
@@ -96,28 +106,23 @@ module C66
|
|
96
106
|
end
|
97
107
|
end
|
98
108
|
|
99
|
-
def
|
100
|
-
if
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
109
|
+
def load_stack(alias_name)
|
110
|
+
if File.exists?(stack_file(alias_name))
|
111
|
+
if file = JSON.load(IO.read(stack_file(alias_name)))
|
112
|
+
if file.has_key? 'stack_id'
|
113
|
+
@stack = file['stack_id']
|
114
|
+
end
|
115
|
+
if file.has_key? 'stack_name' and !@stack.nil?
|
116
|
+
@stack_name = file['stack_name']
|
117
|
+
say "Stack #{@stack_name} loaded."
|
118
|
+
end
|
119
|
+
end
|
106
120
|
end
|
107
|
-
@stack = stack_id
|
108
|
-
say "Stack #{stack_id} saved to #{stack_file}"
|
109
121
|
end
|
110
122
|
|
111
|
-
def
|
112
|
-
|
113
|
-
|
114
|
-
say "Stack #{@stack} loaded."
|
115
|
-
else
|
116
|
-
abort "No stack id found at #{stack_file}"
|
117
|
-
end
|
118
|
-
else
|
119
|
-
say("No stack saved at #{stack_file}.")
|
120
|
-
end
|
123
|
+
def abort_no_stack
|
124
|
+
abort "No stack provided or saved, please use '--stack' or '-s' option. "\
|
125
|
+
"You can also use the 'save' method with '--stack' or '-s' option."
|
121
126
|
end
|
122
127
|
|
123
128
|
def load_params
|
@@ -130,25 +135,28 @@ module C66
|
|
130
135
|
if @params.has_key? 'base_url'
|
131
136
|
values[:base_url] = @params['base_url']
|
132
137
|
else
|
133
|
-
abort "Missing 'base_url' parameter in #{params_file}"
|
138
|
+
abort "Missing 'base_url' parameter in #{params_file}"
|
134
139
|
end
|
135
140
|
if @params.has_key? 'client_id'
|
136
141
|
values[:client_id] = @params['client_id']
|
137
142
|
else
|
138
|
-
abort "Missing 'client_id' parameter in #{params_file}"
|
143
|
+
abort "Missing 'client_id' parameter in #{params_file}"
|
139
144
|
end
|
140
145
|
if @params.has_key? 'client_secret'
|
141
146
|
values[:client_secret] = @params['client_secret']
|
142
147
|
else
|
143
|
-
abort "Missing 'client_secret' parameter in #{params_file}"
|
148
|
+
abort "Missing 'client_secret' parameter in #{params_file}"
|
144
149
|
end
|
145
|
-
say "Parameters loaded."
|
150
|
+
#say "Parameters loaded."
|
146
151
|
end
|
147
152
|
end
|
148
153
|
|
149
|
-
def get_stack(
|
150
|
-
|
151
|
-
|
154
|
+
def get_stack(stack_id_or_alias_name)
|
155
|
+
if stack_id_or_alias_name && !File.exist?(stack_file(stack_id_or_alias_name))
|
156
|
+
@stack=stack_id_or_alias_name
|
157
|
+
else
|
158
|
+
load_stack(stack_id_or_alias_name)
|
159
|
+
end
|
152
160
|
end
|
153
161
|
|
154
162
|
def client
|
@@ -173,33 +181,71 @@ module C66
|
|
173
181
|
end
|
174
182
|
end
|
175
183
|
|
176
|
-
def
|
184
|
+
def error_message(error)
|
177
185
|
begin
|
178
|
-
|
186
|
+
if !error.response.parsed.nil?
|
187
|
+
if (error.response.parsed.has_key? 'details')
|
188
|
+
puts error.response.parsed['details']
|
189
|
+
else
|
190
|
+
puts error.response.parsed['error_description']
|
191
|
+
end
|
192
|
+
end
|
193
|
+
rescue => e
|
194
|
+
abort e.message
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
def get_version
|
199
|
+
begin
|
200
|
+
JSON.load(HTTParty.get(VERSION_FILE).response.body).fetch("version")
|
179
201
|
rescue => e
|
180
202
|
puts "Failed to retrieve the latest version of Cloud 66 Toolbelt, please contact us"
|
181
203
|
end
|
182
204
|
end
|
183
205
|
|
184
|
-
|
185
|
-
|
186
|
-
|
206
|
+
def display_info
|
207
|
+
say "#{CLIENT_FULLNAME} version #{C66::Utils::VERSION}\n\n"
|
208
|
+
end
|
209
|
+
|
210
|
+
def compare_versions
|
211
|
+
result = C66::Utils::VERSION <=> get_version
|
187
212
|
case result
|
188
213
|
when 0..1
|
189
|
-
|
190
|
-
|
191
|
-
|
214
|
+
#say "Version is up-to-date."
|
215
|
+
when -1
|
216
|
+
say "There is a new version of Cloud66 Toolbelt. Pease run \"gem update #{CLIENT_NAME}\".",:red
|
192
217
|
end
|
193
|
-
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def pending_intercom_messages
|
221
|
+
begin
|
222
|
+
result = parse_response(token.get("#{base_url}/users/unread_messages.json"))
|
223
|
+
nb_messages = result['response']['unread_messages']
|
224
|
+
say "You have #{nb_messages} pending message(s), check them out at www.cloud66.com!",:green if nb_messages > 0
|
225
|
+
rescue
|
226
|
+
# nop
|
227
|
+
end
|
228
|
+
end
|
229
|
+
|
230
|
+
def before_each_action
|
231
|
+
display_info
|
232
|
+
compare_versions
|
233
|
+
pending_intercom_messages
|
234
|
+
end
|
194
235
|
}
|
195
236
|
|
196
|
-
package_name "
|
197
|
-
desc "init", "Initialize the toolbelt"
|
198
|
-
map "d" => :deploy
|
237
|
+
package_name "#{CLIENT_FULLNAME}: version #{C66::Utils::VERSION}\n"
|
199
238
|
|
200
|
-
|
201
|
-
|
239
|
+
default_task :default
|
240
|
+
|
241
|
+
desc "default", "hidden method", :hide => true
|
242
|
+
def default
|
243
|
+
before_each_action
|
244
|
+
help
|
245
|
+
end
|
202
246
|
|
247
|
+
desc "init", "Initialize the toolbelt"
|
248
|
+
map "d" => :deploy
|
203
249
|
long_desc <<-LONGDESC
|
204
250
|
Initialize Cloud 66 toolbelt
|
205
251
|
LONGDESC
|
@@ -226,33 +272,42 @@ module C66
|
|
226
272
|
|
227
273
|
desc "list", "Lists all the stacks"
|
228
274
|
def list
|
229
|
-
|
275
|
+
before_each_action
|
276
|
+
begin
|
277
|
+
response = parse_response(token.get("#{base_url}/stacks.json"))
|
230
278
|
|
231
|
-
|
232
|
-
|
233
|
-
|
279
|
+
if response['count'] != 0
|
280
|
+
response['response'].each do |stack|
|
281
|
+
say "#{stack['name']} (#{stack['uid']}) : #{stack['environment']} - #{STATUS[stack['status']]}"
|
282
|
+
end
|
283
|
+
else
|
284
|
+
say "No stacks found"
|
234
285
|
end
|
235
|
-
|
236
|
-
|
286
|
+
rescue OAuth2::Error => e
|
287
|
+
error_message(e)
|
237
288
|
end
|
238
289
|
end
|
239
290
|
|
240
291
|
desc "settings", "Get the list of settings for this stack"
|
241
292
|
option :stack, :aliases => "-s", :required => false
|
242
|
-
def settings
|
293
|
+
def settings
|
294
|
+
before_each_action
|
243
295
|
begin
|
244
296
|
get_stack(options[:stack])
|
245
|
-
|
297
|
+
abort_no_stack if @stack.nil?
|
246
298
|
response = token.get("#{base_url}/stacks/#{@stack}/settings.json")
|
247
299
|
settings = JSON.parse(response.body)['response']
|
300
|
+
number_settings = JSON.parse(response.body)['count']
|
301
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
302
|
+
stack_name = stack_details['response']['name']
|
248
303
|
|
249
304
|
abort "No settings found" if settings.nil?
|
250
|
-
|
305
|
+
say "Getting #{stack_name} settings:"
|
251
306
|
settings.each do |setting|
|
252
307
|
say "#{setting['key']}\t\t#{setting['value']}\t#{setting['readonly'] ? '(readonly)' : ''}\r\n"
|
253
308
|
end
|
254
309
|
rescue OAuth2::Error => e
|
255
|
-
|
310
|
+
error_message(e)
|
256
311
|
end
|
257
312
|
end
|
258
313
|
|
@@ -261,26 +316,87 @@ module C66
|
|
261
316
|
option :setting_name, :aliases => "-n", :required => true
|
262
317
|
option :value, :aliases => "-v", :required => true
|
263
318
|
def set()
|
319
|
+
before_each_action
|
264
320
|
begin
|
265
321
|
get_stack(options[:stack])
|
266
|
-
|
322
|
+
abort_no_stack if @stack.nil?
|
323
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
324
|
+
stack_name = stack_details['response']['name']
|
267
325
|
response = token.post("#{base_url}/stacks/#{@stack}/setting.json", { :body => { :setting_name => options[:setting_name], :setting_value => options[:value] }})
|
268
|
-
say "
|
326
|
+
say "On #{stack_name}: applied value '#{options[:value]}' to setting '#{options[:setting_name]}'" if JSON.parse(response.body)['response']['ok']
|
269
327
|
rescue OAuth2::Error => e
|
270
|
-
|
328
|
+
error_message(e)
|
271
329
|
end
|
272
330
|
end
|
273
331
|
|
274
332
|
desc "deploy", "Deploy the given stack"
|
275
333
|
option :stack, :aliases => "-s", :required => false
|
276
|
-
def deploy
|
334
|
+
def deploy
|
335
|
+
before_each_action
|
277
336
|
begin
|
278
337
|
get_stack(options[:stack])
|
279
|
-
|
338
|
+
abort_no_stack if @stack.nil?
|
339
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
340
|
+
stack_name = stack_details['response']['name']
|
341
|
+
say stack_name+": "
|
280
342
|
response = token.post("#{base_url}/stacks/#{@stack}/redeploy.json", {})
|
281
343
|
say JSON.parse(response.body)['response']['message']
|
282
344
|
rescue OAuth2::Error => e
|
283
|
-
|
345
|
+
error_message(e)
|
346
|
+
end
|
347
|
+
end
|
348
|
+
|
349
|
+
desc "save", "Save the given stack information in the current directory"
|
350
|
+
option :stack, :aliases => "-s", :required => true
|
351
|
+
option :alias, :aliases => "-a", :required => false
|
352
|
+
def save
|
353
|
+
before_each_action
|
354
|
+
begin
|
355
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{options[:stack]}.json"))
|
356
|
+
stack_name = stack_details['response']['name']
|
357
|
+
if !File.directory?(stack_path)
|
358
|
+
Dir.mkdir(stack_path)
|
359
|
+
end
|
360
|
+
@stack_json = { :stack_id => options[:stack], :stack_name => stack_name}
|
361
|
+
File.open(stack_file(options[:alias]),"w") do |f|
|
362
|
+
f.write(@stack_json.to_json)
|
363
|
+
end
|
364
|
+
@stack = options[:stack]
|
365
|
+
|
366
|
+
say "Linked stack #{stack_name} to #{stack_file(options[:alias])}.\n"
|
367
|
+
if !options[:alias]
|
368
|
+
say "You are now able to use other commands without specify the stack UID."
|
369
|
+
else
|
370
|
+
say "You are now able to use other commands and specific this stack's alias, like so: "\
|
371
|
+
"`c66 deploy -s #{options[:alias]}`"
|
372
|
+
end
|
373
|
+
rescue OAuth2::Error => e
|
374
|
+
error_message(e)
|
375
|
+
end
|
376
|
+
end
|
377
|
+
|
378
|
+
desc "info", "#{CLIENT_FULLNAME} information"
|
379
|
+
def info
|
380
|
+
before_each_action
|
381
|
+
begin
|
382
|
+
say "#{CLIENT_FULLNAME} version #{C66::Utils::VERSION}\n\n"
|
383
|
+
Dir.glob("#{stack_path}/*.json") do |stack_file|
|
384
|
+
stack_alias = File.basename(stack_file, ".json")
|
385
|
+
load_stack(stack_alias)
|
386
|
+
if stack_alias == "stack"
|
387
|
+
say "Default stack: no alias"
|
388
|
+
else
|
389
|
+
say "Alias: #{stack_alias}"
|
390
|
+
end
|
391
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
392
|
+
say "Name: #{stack_details['response']['name']}"
|
393
|
+
say "UID: #{stack_details['response']['uid']}"
|
394
|
+
say "Environment: #{stack_details['response']['environment']}"
|
395
|
+
say "Status: #{STATUS[stack_details['response']['status']]}\n\n"
|
396
|
+
end
|
397
|
+
rescue OAuth2::Error => e
|
398
|
+
puts "Didn't find any valid stack, please use the 'save' method."
|
399
|
+
error_message(e)
|
284
400
|
end
|
285
401
|
end
|
286
402
|
end
|
data/lib/c66/utils/version.rb
CHANGED
data/toolbelt.go
ADDED
@@ -0,0 +1,125 @@
|
|
1
|
+
package main
|
2
|
+
|
3
|
+
import "fmt"
|
4
|
+
import "code.google.com/p/goauth2/oauth"
|
5
|
+
import "log"
|
6
|
+
import "encoding/json"
|
7
|
+
import "io/ioutil"
|
8
|
+
import "flag"
|
9
|
+
|
10
|
+
// 5d9194b2a080d353ab2b8324d742933d9627f46c192be964a7527659caa15abf
|
11
|
+
var (
|
12
|
+
baseURL = "https://www.cloud66.com/api/2"
|
13
|
+
clientId = "638412995ee3da6f67e24564ac297f9554ee253a8fe1502348c4d6e845bd9d0d"
|
14
|
+
clientSecret = "961398353aa6e7f0f36dfcd83e447d748c54481b7a3b143e0119441516e8b91f"
|
15
|
+
scope = "public redeploy"
|
16
|
+
redirectURL = "urn:ietf:wg:oauth:2.0:oob"
|
17
|
+
authURL = "https://www.cloud66.com/oauth/authorize"
|
18
|
+
tokenURL = "https://www.cloud66.com/oauth/token"
|
19
|
+
cachefile = flag.String("cache", "/tmp/c66_toolbelt.json", "Token cache file")
|
20
|
+
code = flag.String("code", "", "Authorization Code")
|
21
|
+
stackUid = flag.String("stack", "", "Stack Uid")
|
22
|
+
statusDics = make(map[int]string)
|
23
|
+
)
|
24
|
+
|
25
|
+
func main() {
|
26
|
+
setup()
|
27
|
+
// get the command
|
28
|
+
command := flag.String("command", "", "Command to run")
|
29
|
+
|
30
|
+
flag.Parse()
|
31
|
+
|
32
|
+
switch *command {
|
33
|
+
case "deploy": deploy()
|
34
|
+
case "init": initialize()
|
35
|
+
case "stacks" : listStacks()
|
36
|
+
default: fmt.Println("unknown command")
|
37
|
+
}
|
38
|
+
}
|
39
|
+
|
40
|
+
func deploy() {
|
41
|
+
transport := initialize()
|
42
|
+
requestURL := baseURL + "/stacks/" + *stackUid + "/redeploy.json"
|
43
|
+
|
44
|
+
r, err := transport.Client().Post(requestURL, "application/json", nil)
|
45
|
+
if err != nil {
|
46
|
+
log.Fatal("Get:", err)
|
47
|
+
}
|
48
|
+
defer r.Body.Close()
|
49
|
+
result, _ := ioutil.ReadAll(r.Body)
|
50
|
+
fmt.Println(string(result))
|
51
|
+
}
|
52
|
+
|
53
|
+
type Result struct {
|
54
|
+
Stacks []Stack `json:"response"`
|
55
|
+
}
|
56
|
+
|
57
|
+
type Stack struct {
|
58
|
+
Uid string`json:"uid"`
|
59
|
+
Name string `json:"name"`
|
60
|
+
Status int `json:"status"`
|
61
|
+
}
|
62
|
+
|
63
|
+
func setup() {
|
64
|
+
statusDics[0] = "Pending analysis"
|
65
|
+
statusDics[1] = "Deployed successfully"
|
66
|
+
statusDics[2] = "Deployment failed"
|
67
|
+
statusDics[3] = "Analyzing"
|
68
|
+
statusDics[4] = "Analyzed"
|
69
|
+
statusDics[5] = "Queued for deployment"
|
70
|
+
statusDics[6] = "Deploying"
|
71
|
+
statusDics[7] = "Unable to analyze"
|
72
|
+
}
|
73
|
+
|
74
|
+
func listStacks() {
|
75
|
+
transport := initialize()
|
76
|
+
requestURL := baseURL + "/stacks.json"
|
77
|
+
|
78
|
+
r, err := transport.Client().Get(requestURL)
|
79
|
+
if err != nil {
|
80
|
+
log.Fatal("Get:", err)
|
81
|
+
}
|
82
|
+
defer r.Body.Close()
|
83
|
+
result, _ := ioutil.ReadAll(r.Body)
|
84
|
+
|
85
|
+
var response Result
|
86
|
+
if err := json.Unmarshal(result, &response); err != nil {
|
87
|
+
panic(err)
|
88
|
+
} else {
|
89
|
+
for i := 0; i < len(response.Stacks); i++ {
|
90
|
+
stack := response.Stacks[i]
|
91
|
+
fmt.Printf("%v (%v) - %s\n", stack.Name, stack.Uid, statusDics[stack.Status])
|
92
|
+
}
|
93
|
+
}
|
94
|
+
}
|
95
|
+
|
96
|
+
func initialize() (*oauth.Transport){
|
97
|
+
config := &oauth.Config{
|
98
|
+
ClientId: clientId,
|
99
|
+
ClientSecret: clientSecret,
|
100
|
+
RedirectURL: redirectURL,
|
101
|
+
Scope: scope,
|
102
|
+
AuthURL: authURL,
|
103
|
+
TokenURL: tokenURL,
|
104
|
+
TokenCache: oauth.CacheFile(*cachefile),
|
105
|
+
}
|
106
|
+
transport := &oauth.Transport{Config: config}
|
107
|
+
token, err := config.TokenCache.Token()
|
108
|
+
if err != nil {
|
109
|
+
if *code == "" {
|
110
|
+
url := config.AuthCodeURL("")
|
111
|
+
fmt.Println("Visit this URL to get a code, then run again with -code=YOUR_CODE\n")
|
112
|
+
fmt.Println(url)
|
113
|
+
return nil
|
114
|
+
}
|
115
|
+
token, err = transport.Exchange(*code)
|
116
|
+
if err != nil {
|
117
|
+
log.Fatal("Exchange:", err)
|
118
|
+
}
|
119
|
+
fmt.Printf("Token is cached in %v\n", config.TokenCache)
|
120
|
+
}
|
121
|
+
|
122
|
+
transport.Token = token
|
123
|
+
|
124
|
+
return transport
|
125
|
+
}
|
metadata
CHANGED
@@ -1,123 +1,171 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: c66
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 11
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 8
|
10
|
+
version: 0.1.8
|
6
11
|
platform: ruby
|
7
|
-
authors:
|
12
|
+
authors:
|
8
13
|
- Cloud 66
|
9
14
|
autorequire:
|
10
15
|
bindir: bin
|
11
16
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
17
|
+
|
18
|
+
date: 2013-07-25 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
15
21
|
name: bundler
|
16
|
-
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
17
24
|
none: false
|
18
|
-
requirements:
|
25
|
+
requirements:
|
19
26
|
- - ~>
|
20
|
-
- !ruby/object:Gem::Version
|
21
|
-
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 9
|
29
|
+
segments:
|
30
|
+
- 1
|
31
|
+
- 3
|
32
|
+
version: "1.3"
|
22
33
|
type: :runtime
|
23
|
-
|
24
|
-
|
25
|
-
- !ruby/object:Gem::Dependency
|
34
|
+
version_requirements: *id001
|
35
|
+
- !ruby/object:Gem::Dependency
|
26
36
|
name: rake
|
27
|
-
|
37
|
+
prerelease: false
|
38
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
28
39
|
none: false
|
29
|
-
requirements:
|
40
|
+
requirements:
|
30
41
|
- - ~>
|
31
|
-
- !ruby/object:Gem::Version
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
hash: 75
|
44
|
+
segments:
|
45
|
+
- 10
|
46
|
+
- 1
|
47
|
+
- 0
|
32
48
|
version: 10.1.0
|
33
49
|
type: :runtime
|
34
|
-
|
35
|
-
|
36
|
-
- !ruby/object:Gem::Dependency
|
50
|
+
version_requirements: *id002
|
51
|
+
- !ruby/object:Gem::Dependency
|
37
52
|
name: thor
|
38
|
-
|
53
|
+
prerelease: false
|
54
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
39
55
|
none: false
|
40
|
-
requirements:
|
56
|
+
requirements:
|
41
57
|
- - ~>
|
42
|
-
- !ruby/object:Gem::Version
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
hash: 85
|
60
|
+
segments:
|
61
|
+
- 0
|
62
|
+
- 18
|
63
|
+
- 1
|
43
64
|
version: 0.18.1
|
44
65
|
type: :runtime
|
45
|
-
|
46
|
-
|
47
|
-
- !ruby/object:Gem::Dependency
|
66
|
+
version_requirements: *id003
|
67
|
+
- !ruby/object:Gem::Dependency
|
48
68
|
name: oauth2
|
49
|
-
|
69
|
+
prerelease: false
|
70
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
50
71
|
none: false
|
51
|
-
requirements:
|
72
|
+
requirements:
|
52
73
|
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
hash: 63
|
76
|
+
segments:
|
77
|
+
- 0
|
78
|
+
- 9
|
79
|
+
- 2
|
54
80
|
version: 0.9.2
|
55
81
|
type: :runtime
|
56
|
-
|
57
|
-
|
58
|
-
- !ruby/object:Gem::Dependency
|
82
|
+
version_requirements: *id004
|
83
|
+
- !ruby/object:Gem::Dependency
|
59
84
|
name: json
|
60
|
-
|
85
|
+
prerelease: false
|
86
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
61
87
|
none: false
|
62
|
-
requirements:
|
88
|
+
requirements:
|
63
89
|
- - ~>
|
64
|
-
- !ruby/object:Gem::Version
|
90
|
+
- !ruby/object:Gem::Version
|
91
|
+
hash: 5
|
92
|
+
segments:
|
93
|
+
- 1
|
94
|
+
- 7
|
95
|
+
- 7
|
65
96
|
version: 1.7.7
|
66
97
|
type: :runtime
|
67
|
-
|
68
|
-
|
69
|
-
- !ruby/object:Gem::Dependency
|
98
|
+
version_requirements: *id005
|
99
|
+
- !ruby/object:Gem::Dependency
|
70
100
|
name: httparty
|
71
|
-
|
101
|
+
prerelease: false
|
102
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
72
103
|
none: false
|
73
|
-
requirements:
|
104
|
+
requirements:
|
74
105
|
- - ~>
|
75
|
-
- !ruby/object:Gem::Version
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
hash: 51
|
108
|
+
segments:
|
109
|
+
- 0
|
110
|
+
- 11
|
111
|
+
- 0
|
76
112
|
version: 0.11.0
|
77
113
|
type: :runtime
|
78
|
-
|
79
|
-
version_requirements: *70093107962820
|
114
|
+
version_requirements: *id006
|
80
115
|
description: See https://www.cloud66.com for more info
|
81
|
-
email:
|
116
|
+
email:
|
82
117
|
- hello@cloud66.com
|
83
|
-
executables:
|
84
|
-
- c66
|
118
|
+
executables:
|
119
|
+
- c66
|
85
120
|
extensions: []
|
121
|
+
|
86
122
|
extra_rdoc_files: []
|
87
|
-
|
123
|
+
|
124
|
+
files:
|
88
125
|
- .gitignore
|
89
126
|
- Gemfile
|
127
|
+
- Gemfile.lock
|
90
128
|
- LICENSE.txt
|
91
129
|
- README.md
|
92
130
|
- Rakefile
|
93
|
-
- bin/c66
|
131
|
+
- bin/c66
|
94
132
|
- c66.gemspec
|
95
133
|
- lib/c66.rb
|
96
134
|
- lib/c66/commands/c66_toolbelt.rb
|
97
135
|
- lib/c66/utils/version.rb
|
136
|
+
- toolbelt.go
|
98
137
|
homepage: https://www.cloud66.com
|
99
|
-
licenses:
|
138
|
+
licenses:
|
100
139
|
- MIT
|
101
140
|
post_install_message:
|
102
141
|
rdoc_options: []
|
103
|
-
|
142
|
+
|
143
|
+
require_paths:
|
104
144
|
- lib
|
105
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
145
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
106
146
|
none: false
|
107
|
-
requirements:
|
108
|
-
- -
|
109
|
-
- !ruby/object:Gem::Version
|
110
|
-
|
111
|
-
|
147
|
+
requirements:
|
148
|
+
- - ">="
|
149
|
+
- !ruby/object:Gem::Version
|
150
|
+
hash: 3
|
151
|
+
segments:
|
152
|
+
- 0
|
153
|
+
version: "0"
|
154
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
112
155
|
none: false
|
113
|
-
requirements:
|
114
|
-
- -
|
115
|
-
- !ruby/object:Gem::Version
|
116
|
-
|
156
|
+
requirements:
|
157
|
+
- - ">="
|
158
|
+
- !ruby/object:Gem::Version
|
159
|
+
hash: 3
|
160
|
+
segments:
|
161
|
+
- 0
|
162
|
+
version: "0"
|
117
163
|
requirements: []
|
164
|
+
|
118
165
|
rubyforge_project:
|
119
|
-
rubygems_version: 1.8.
|
166
|
+
rubygems_version: 1.8.12
|
120
167
|
signing_key:
|
121
168
|
specification_version: 3
|
122
169
|
summary: Cloud 66 Toolbelt
|
123
170
|
test_files: []
|
171
|
+
|
/data/bin/{c66.rb → c66}
RENAMED
File without changes
|