c66 0.1.0 → 0.1.9
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 +174 -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.9)
|
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.8)
|
16
|
+
multipart-post (~> 1.2.0)
|
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.4.5)
|
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,70 @@ 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
|
+
compare_versions
|
232
|
+
# pending_intercom_messages
|
233
|
+
end
|
194
234
|
}
|
195
235
|
|
196
|
-
package_name "
|
197
|
-
desc "init", "Initialize the toolbelt"
|
198
|
-
map "d" => :deploy
|
236
|
+
package_name "#{CLIENT_FULLNAME}: version #{C66::Utils::VERSION}\n"
|
199
237
|
|
200
|
-
|
201
|
-
|
238
|
+
default_task :default
|
202
239
|
|
240
|
+
desc "default", "hidden method", :hide => true
|
241
|
+
def default
|
242
|
+
before_each_action
|
243
|
+
help
|
244
|
+
end
|
245
|
+
|
246
|
+
desc "init", "Initialize the toolbelt"
|
247
|
+
map "d" => :deploy
|
203
248
|
long_desc <<-LONGDESC
|
204
249
|
Initialize Cloud 66 toolbelt
|
205
250
|
LONGDESC
|
@@ -226,33 +271,42 @@ module C66
|
|
226
271
|
|
227
272
|
desc "list", "Lists all the stacks"
|
228
273
|
def list
|
229
|
-
|
274
|
+
before_each_action
|
275
|
+
begin
|
276
|
+
response = parse_response(token.get("#{base_url}/stacks.json"))
|
230
277
|
|
231
|
-
|
232
|
-
|
233
|
-
|
278
|
+
if response['count'] != 0
|
279
|
+
response['response'].each do |stack|
|
280
|
+
say "#{stack['name']} (#{stack['uid']}) : #{stack['environment']} - #{STATUS[stack['status']]}"
|
281
|
+
end
|
282
|
+
else
|
283
|
+
say "No stacks found"
|
234
284
|
end
|
235
|
-
|
236
|
-
|
285
|
+
rescue OAuth2::Error => e
|
286
|
+
error_message(e)
|
237
287
|
end
|
238
288
|
end
|
239
289
|
|
240
290
|
desc "settings", "Get the list of settings for this stack"
|
241
291
|
option :stack, :aliases => "-s", :required => false
|
242
|
-
def settings
|
292
|
+
def settings
|
293
|
+
before_each_action
|
243
294
|
begin
|
244
295
|
get_stack(options[:stack])
|
245
|
-
|
296
|
+
abort_no_stack if @stack.nil?
|
246
297
|
response = token.get("#{base_url}/stacks/#{@stack}/settings.json")
|
247
298
|
settings = JSON.parse(response.body)['response']
|
299
|
+
number_settings = JSON.parse(response.body)['count']
|
300
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
301
|
+
stack_name = stack_details['response']['name']
|
248
302
|
|
249
303
|
abort "No settings found" if settings.nil?
|
250
|
-
|
304
|
+
say "Getting #{stack_name} settings:"
|
251
305
|
settings.each do |setting|
|
252
306
|
say "#{setting['key']}\t\t#{setting['value']}\t#{setting['readonly'] ? '(readonly)' : ''}\r\n"
|
253
307
|
end
|
254
308
|
rescue OAuth2::Error => e
|
255
|
-
|
309
|
+
error_message(e)
|
256
310
|
end
|
257
311
|
end
|
258
312
|
|
@@ -261,26 +315,87 @@ module C66
|
|
261
315
|
option :setting_name, :aliases => "-n", :required => true
|
262
316
|
option :value, :aliases => "-v", :required => true
|
263
317
|
def set()
|
318
|
+
before_each_action
|
264
319
|
begin
|
265
320
|
get_stack(options[:stack])
|
266
|
-
|
321
|
+
abort_no_stack if @stack.nil?
|
322
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
323
|
+
stack_name = stack_details['response']['name']
|
267
324
|
response = token.post("#{base_url}/stacks/#{@stack}/setting.json", { :body => { :setting_name => options[:setting_name], :setting_value => options[:value] }})
|
268
|
-
say "
|
325
|
+
say "On #{stack_name}: applied value '#{options[:value]}' to setting '#{options[:setting_name]}'" if JSON.parse(response.body)['response']['ok']
|
269
326
|
rescue OAuth2::Error => e
|
270
|
-
|
327
|
+
error_message(e)
|
271
328
|
end
|
272
329
|
end
|
273
330
|
|
274
331
|
desc "deploy", "Deploy the given stack"
|
275
332
|
option :stack, :aliases => "-s", :required => false
|
276
|
-
def deploy
|
333
|
+
def deploy
|
334
|
+
before_each_action
|
277
335
|
begin
|
278
336
|
get_stack(options[:stack])
|
279
|
-
|
337
|
+
abort_no_stack if @stack.nil?
|
338
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
339
|
+
stack_name = stack_details['response']['name']
|
340
|
+
say stack_name+": "
|
280
341
|
response = token.post("#{base_url}/stacks/#{@stack}/redeploy.json", {})
|
281
342
|
say JSON.parse(response.body)['response']['message']
|
282
343
|
rescue OAuth2::Error => e
|
283
|
-
|
344
|
+
error_message(e)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
desc "save", "Save the given stack information in the current directory"
|
349
|
+
option :stack, :aliases => "-s", :required => true
|
350
|
+
option :alias, :aliases => "-a", :required => false
|
351
|
+
def save
|
352
|
+
before_each_action
|
353
|
+
begin
|
354
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{options[:stack]}.json"))
|
355
|
+
stack_name = stack_details['response']['name']
|
356
|
+
if !File.directory?(stack_path)
|
357
|
+
Dir.mkdir(stack_path)
|
358
|
+
end
|
359
|
+
@stack_json = { :stack_id => options[:stack], :stack_name => stack_name}
|
360
|
+
File.open(stack_file(options[:alias]),"w") do |f|
|
361
|
+
f.write(@stack_json.to_json)
|
362
|
+
end
|
363
|
+
@stack = options[:stack]
|
364
|
+
|
365
|
+
say "Linked stack #{stack_name} to #{stack_file(options[:alias])}.\n"
|
366
|
+
if !options[:alias]
|
367
|
+
say "You are now able to use other commands without specify the stack UID."
|
368
|
+
else
|
369
|
+
say "You are now able to use other commands and specific this stack's alias, like so: "\
|
370
|
+
"`c66 deploy -s #{options[:alias]}`"
|
371
|
+
end
|
372
|
+
rescue OAuth2::Error => e
|
373
|
+
error_message(e)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
desc "info", "#{CLIENT_FULLNAME} information"
|
378
|
+
def info
|
379
|
+
before_each_action
|
380
|
+
begin
|
381
|
+
say "#{CLIENT_FULLNAME} version #{C66::Utils::VERSION}\n\n"
|
382
|
+
Dir.glob("#{stack_path}/*.json") do |stack_file|
|
383
|
+
stack_alias = File.basename(stack_file, ".json")
|
384
|
+
load_stack(stack_alias)
|
385
|
+
if stack_alias == "stack"
|
386
|
+
say "Default stack: no alias"
|
387
|
+
else
|
388
|
+
say "Alias: #{stack_alias}"
|
389
|
+
end
|
390
|
+
stack_details = parse_response(token.get("#{base_url}/stacks/#{@stack}.json"))
|
391
|
+
say "Name: #{stack_details['response']['name']}"
|
392
|
+
say "UID: #{stack_details['response']['uid']}"
|
393
|
+
say "Environment: #{stack_details['response']['environment']}"
|
394
|
+
say "Status: #{STATUS[stack_details['response']['status']]}\n\n"
|
395
|
+
end
|
396
|
+
rescue OAuth2::Error => e
|
397
|
+
puts "Didn't find any valid stack, please use the 'save' method."
|
398
|
+
error_message(e)
|
284
399
|
end
|
285
400
|
end
|
286
401
|
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: 9
|
5
5
|
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 9
|
10
|
+
version: 0.1.9
|
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-08-05 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
|