blend 0.1.4

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.
@@ -0,0 +1,38 @@
1
+ require 'blend/cli/hipchat'
2
+ require 'blend/cli/github'
3
+ require 'blend/cli/juice'
4
+ require 'blend/cli/heroku'
5
+
6
+ module Blend
7
+ module CLI
8
+ class CLI < Thor
9
+
10
+ desc "logout", "Clear juice credentials"
11
+ def logout
12
+ Blend::CLI::Juice.new.logout
13
+ end
14
+
15
+ desc "login", "Acquire juice credentials"
16
+ def login
17
+ Blend::CLI::Juice.new.login
18
+ end
19
+
20
+ desc 'projects', 'List of Juice projects'
21
+ def projects
22
+ Blend::CLI::Juice.new.projects
23
+ end
24
+
25
+ desc "hipchat COMMANDS", "Hipchat Control Module"
26
+ subcommand "hipchat", Blend::CLI::Hipchat
27
+
28
+ desc "github COMMANDS", "Github Control Module"
29
+ subcommand "github", Blend::CLI::Github
30
+
31
+ desc "juice COMMANDS", "Juice Control Module"
32
+ subcommand "juice", Blend::CLI::Juice
33
+
34
+ desc "heroku COMMANDS", "Heroku Control Module"
35
+ subcommand "heroku", Blend::CLI::Heroku
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,140 @@
1
+ module Blend
2
+ module CLI
3
+ class Github < Thor
4
+ desc "hooks REPO", "Lists out service hooks for a given repo"
5
+ def hooks( repo )
6
+ puts
7
+ printf "%-20s %-60s\n".blue.underline, 'Name', 'Config'
8
+ client.list_hooks( repo ).each do |hook|
9
+ printf "%-20s", hook.name
10
+ cfg = hook.config.collect{|k,v| [k,v]}
11
+ if hook.config.count > 0
12
+ cfg.each_with_index do |(k,v),i|
13
+ if i>0
14
+ printf "%-20s %-20s: %-20s\n", '', k, v.inspect
15
+ else
16
+ printf " %-20s: %-20s\n", k, v.inspect
17
+ end
18
+ end
19
+ else
20
+ puts "\n"
21
+ end
22
+ puts
23
+ end
24
+ end
25
+
26
+ desc "add_hipchat REPO ROOM", "Add hipchat hook to repo"
27
+ def add_hipchat( repo, room )
28
+ client.add_hook( repo, "hipchat", {
29
+ auth_token: Blend::Client::get_token( :hipchat ),
30
+ notify: "1",
31
+ restrict_to_branch: "",
32
+ room: room } )
33
+ Blend::Client::hipchat_client.post_message room, "#{repo} commit hook now added"
34
+ end
35
+
36
+ desc "repos", "Lists out the repos"
37
+ def repos
38
+ puts
39
+ printf "%-50s %-40s\n".blue.underline, 'Name', 'Description'
40
+ client.list_repos.each do |repo|
41
+ printf "%-50s %-40s\n", repo['full_name'], repo['description']
42
+ end
43
+ puts
44
+ end
45
+
46
+ desc "repo_search NAME", "Lists out matching repos"
47
+ def repo_search( name )
48
+ puts
49
+ printf "%-50s %-40s\n".blue.underline, 'Name', 'Description'
50
+ client.list_repos(name).each do |repo|
51
+ printf "%-50s %-40s\n", repo['full_name'], repo['description']
52
+ end
53
+ puts
54
+ end
55
+
56
+ desc "repo_create TEAM, NAME", "Create team repo"
57
+ def repo_create( team, name )
58
+ client.repo_create( team, name )
59
+ team( team )
60
+ end
61
+
62
+
63
+ desc "collaborators REPO", "List out collaborators"
64
+ def collaborators( repo )
65
+ client.list_collaborators( repo ).each do |collaborator|
66
+ puts collaborator['login']
67
+ end
68
+ end
69
+
70
+ desc "teams", "List out organizations team"
71
+ def teams
72
+ client.list_teams.each do |team|
73
+ puts team.name
74
+ end
75
+ end
76
+
77
+ desc "team_repos TEAM", "List out a teams repos"
78
+ def team_repos( team )
79
+ puts
80
+ printf "%-40s %-40s\n".blue.underline, 'Name', 'Description'
81
+ client.list_team_repos( team ).each do |repo|
82
+ printf "%-40s %-40s\n", repo['full_name'], repo['description']
83
+ end
84
+ puts
85
+ end
86
+
87
+ desc "team TEAM", "List out the team"
88
+ def team( team )
89
+ puts
90
+ printf "%-40s %-40s\n".blue.underline, 'Repo name', 'Description'
91
+ client.list_team_repos( team ).each do |repo|
92
+ printf "%-40s %s\n", repo['full_name'], repo['description']
93
+ end
94
+ puts
95
+ printf "%-30s\n".blue.underline, 'Github users'
96
+ client.list_team_members( team ).each do |user|
97
+ printf "%s\n", user['login']
98
+ end
99
+ puts
100
+ end
101
+
102
+ desc "team_create TEAM", "Create a team"
103
+ def team_create( team )
104
+ client.create_team( team )
105
+ team( team )
106
+ end
107
+
108
+ desc "team_add TEAM, USER", "Add a user to a team"
109
+ def team_add( team, user )
110
+ client.add_team_member( team, user )
111
+ team( team )
112
+ end
113
+
114
+ desc "team_rm TEAM, USER", "Remove a user from a team"
115
+ def team_rm( team, user)
116
+ client.remove_team_member( team, user )
117
+ team( team )
118
+ end
119
+
120
+ desc "team_repo_add TEAM, REPO", "Add a repo to a team"
121
+ def team_repo_add( team, repo )
122
+ client.add_team_repo( team, repo )
123
+ team( team )
124
+ end
125
+
126
+ desc "team_repo_rm TEAM, REPO", "Remove a repo from a team"
127
+ def team_repo_rm( team, repo )
128
+ client.remove_team_repo( team, repo )
129
+ team( team )
130
+ end
131
+
132
+ no_commands do
133
+ def client
134
+ @client ||= Blend::Client.github_client
135
+ end
136
+ end
137
+
138
+ end
139
+ end
140
+ end
@@ -0,0 +1,232 @@
1
+ module Blend
2
+ module CLI
3
+ class Heroku < Thor
4
+
5
+ desc "info [APP]", "Prints info for a given app"
6
+ def info( app )
7
+ puts
8
+ _info = client.info(app)
9
+ _info.reject{|x| %w(domain_name).include? x}.each do |k,v|
10
+ printf "%35s: %-25s\n", k, v
11
+ end
12
+ puts
13
+ end
14
+
15
+ desc 'domains [APP]', 'Print domain info'
16
+ def domains(app)
17
+ d = client.domains(app)
18
+ d.each do |params|
19
+ puts "\n#{params['domain']}:".blue
20
+ params.each do |k,v|
21
+ printf "%15s: %-25s\n", k, v
22
+ end
23
+ end
24
+ puts
25
+ end
26
+
27
+ desc 'check_domains [APP]', 'Check domains'
28
+ def check_domains(app)
29
+ client.nonheroku_domains(app).each do |domain|
30
+ puts "\nChecking domain #{domain}:".blue
31
+ result = DomainChecker.check(domain)
32
+
33
+ if result.include? :error
34
+ puts result[:error].red
35
+ return
36
+ end
37
+
38
+ # Check registration
39
+ if result[:registered]
40
+ r = result[:registrar]
41
+
42
+ # Registrar:
43
+ if r.nil?
44
+ printf "%25s: %s", 'Registrar', format_result(:warn, "DNS not configured correctly for #{domain}")
45
+ else
46
+ registrar = [r['name'], r['organization'], r['url']].reject(&:nil?).join('; ')
47
+ printf "%25s: %s", 'Registrar', format_result(:pass, registrar)
48
+ end
49
+ else
50
+ printf "%25s: %s", 'Registrar', format_result(:fail)
51
+ end
52
+
53
+
54
+ unless result[:expires].nil?
55
+ # Expiration:
56
+ days_to_expiration = ((result[:expires] - Time.now)/(3600.0*24.0)).to_i
57
+ formatted_dte = "#{result[:expires].strftime("%F")} (#{days_to_expiration} days from now)"
58
+ if days_to_expiration < 30
59
+ state = :fail
60
+ elsif days_to_expiration < 30*3
61
+ state = :warn
62
+ else
63
+ state = :pass
64
+ end
65
+
66
+ printf "%25s: %s", 'Expiration date', format_result(state, formatted_dte)
67
+ end
68
+
69
+ printf "%25s:\n", 'DNS'
70
+ result[:dns].each do |k,v|
71
+ v[:domains].each do |record|
72
+ if record[:type] == 'MX'
73
+ description = "#{record[:data][0]}: #{record[:data][1].to_s}"
74
+ else
75
+ description = record[:data].to_s
76
+ end
77
+ printf "%25s ", ''
78
+ printf "%5s".green, record[:type].to_s
79
+ printf "( ttl=%i ): %s\n", record[:ttl], description
80
+ end
81
+ end
82
+
83
+ end
84
+ end
85
+
86
+ desc 'check_log_monitoring_addon [APP]', 'Check for log monitoring add-on'
87
+ def check_log_monitoring_addon(app)
88
+ a = client.addons(app, /(logentries|keen|papertrail|loggly|flydata)/)
89
+ names = a.collect{|x| x['name']}.join(', ')
90
+ result = a.count > 0 ? format_result(:pass, names) : result = format_result(:fail)
91
+ printf "%25s: %s", 'Log monitoring add-on', result
92
+ end
93
+
94
+ desc 'check_app_monitoring_addon [APP]', 'Check for app monitoring add-on'
95
+ def check_app_monitoring_addon(app)
96
+ a = client.addons(app, /(relic)/)
97
+ names = a.collect{|x| x['name']}.join(', ')
98
+ result = a.count > 0 ? format_result(:pass, names) : result = format_result(:fail)
99
+ printf "%25s: %s", 'App monitoring add-on', result
100
+ end
101
+
102
+ desc 'check_exception_handling_addon [APP]', 'Check for exception handling add-on'
103
+ def check_exception_handling_addon(app)
104
+ a = client.addons(app, /(airbrake|exceptional)/)
105
+ names = a.collect{|x| x['name']}.join(', ')
106
+ result = a.count > 0 ? format_result(:pass, names) : format_result(:fail)
107
+ printf "%25s: %s", 'Exception handling add-on', result
108
+ end
109
+
110
+ desc 'check_deployhooks_appon [APP]', 'Check for deployhooks handling add-on'
111
+ def check_deployhooks_appon(app)
112
+ a = client.addons(app, /deploynooks/)
113
+ names = a.collect{|x| x['name']}.join(', ')
114
+ result = a.count > 0 ? format_result(:pass, names) : format_result(:fail)
115
+ printf "%25s: %s", 'Deploy hooks add-on', result
116
+ end
117
+
118
+
119
+ desc 'check_ssl_addon [APP]', 'Check for SSL addon'
120
+ def check_ssl_addon(app)
121
+ a = client.addons(app, /ssl/)
122
+ names = a.collect{|x| x['name']}.join(', ')
123
+ result = a.count > 0 ? format_result(:pass, names) : format_result(:warn)
124
+ printf "%25s: %s", 'SSL add-on', result
125
+ end
126
+
127
+
128
+ desc "addons [APP]", "Print addons for a given app"
129
+ def addons(app)
130
+ _addons = client.addons(app)
131
+ _addons.each do |addon|
132
+ puts addon['name']
133
+ end
134
+ end
135
+
136
+ desc "addon_price [APP]", "Show the price of app addons"
137
+ def addon_price(app)
138
+ _addons = client.addons(app)
139
+ _addons.each do |addon|
140
+ printf "%-35s: $%10.2f / %-10s\n", addon['name'], addon['price']['cents'].to_i*0.01, addon['price']['unit']
141
+ end
142
+ end
143
+
144
+ desc "check_backups [APP]", "Check to make sure the app is properly set up"
145
+ def check_backups(app)
146
+ printf "%25s: ", "Database backups"
147
+ b = client.backups(app)
148
+ if b.count==0
149
+ printf format_result(:fail)
150
+ else
151
+ printf format_result(:pass, b.collect{|x| x[:plan]}.join(', '))
152
+ end
153
+ end
154
+
155
+ desc 'check_database [APP]', 'Make sure we\'re running a production database'
156
+ def check_database(app)
157
+ printf "%25s: ", "Databases"
158
+ b = client.databases(app)
159
+ unique_plans = b.collect{|x| x[:plan]}.uniq
160
+ if b.nil?
161
+ printf format_result(:fail)
162
+ elsif unique_plans.count==1 and unique_plans[0]=='dev'
163
+ printf format_result(:warn, b.collect{|x| x[:plan]}.join(', '))
164
+ else
165
+ printf format_result(:pass, b.collect{|x| x[:plan]}.join(', '))
166
+ end
167
+ end
168
+
169
+ desc 'check_dyno_redundancy [APP]', 'Make sure more than one dyno is assigned'
170
+ def check_dyno_redundancy(app)
171
+ printf "%25s: ", "Dyno redundancy"
172
+ d = client.dynos(app).to_i
173
+ if d > 1
174
+ printf format_result(:pass, "#{d} dynos")
175
+ else
176
+ printf format_result(:fail, "#{d} dyno")
177
+ end
178
+ end
179
+
180
+ desc 'check_stack [APP]', 'Make sure app is on cedar stack'
181
+ def check_stack(app)
182
+ printf "%25s: ", "Cedar stack"
183
+ s = client.stack(app)
184
+ if s == 'cedar'
185
+ printf format_result(:pass, s)
186
+ else
187
+ printf format_result(:fail, s)
188
+ end
189
+ end
190
+
191
+
192
+ desc 'check [APP]', 'Run production check for app'
193
+ def check(app)
194
+ puts
195
+ puts "Checking app #{app}:".blue
196
+ check_dyno_redundancy(app)
197
+ check_database(app)
198
+ check_backups(app)
199
+ check_stack(app)
200
+ check_exception_handling_addon(app)
201
+ check_deployhooks_appon(app)
202
+ check_log_monitoring_addon(app)
203
+ check_app_monitoring_addon(app)
204
+ check_ssl_addon(app)
205
+ check_domains(app)
206
+ puts
207
+ end
208
+
209
+
210
+
211
+ no_commands do
212
+ def client
213
+ @client ||= Blend::Client.heroku_client
214
+ end
215
+ end
216
+
217
+ no_tasks do
218
+ def format_result( state, message=nil )
219
+ case state
220
+ when :pass
221
+ sprintf "\u2713 #{message}\n".encode('utf-8').green
222
+ when :warn
223
+ sprintf "\u2718 #{message}\n".encode('utf-8').yellow
224
+ when :fail
225
+ sprintf "\u2718 #{message}\n".encode('utf-8').red
226
+ end
227
+ end
228
+ end
229
+
230
+ end
231
+ end
232
+ end
@@ -0,0 +1,61 @@
1
+ module Blend
2
+ module CLI
3
+ class Hipchat < Thor
4
+ desc "rooms", "Show all hipchat rooms"
5
+ def rooms
6
+ client.rooms.sort do
7
+ |b,a| a['last_active'].to_i <=> b['last_active'].to_i
8
+ end.each do |r|
9
+ printf "%6s %-35s %10s %s\n", r['room_id'], r['name'], r['last_active'], r['topic']
10
+ end
11
+ end
12
+
13
+ desc "room ROOM", "Show room info"
14
+ def room( room )
15
+ room_info = client.room_info( room )
16
+ puts "Name : #{room_info['name']}"
17
+ puts "ID : #{room_info['room_id']}"
18
+ puts "Topic : #{room_info['topic']}"
19
+ puts "Last active : #{room_info['last_active']}"
20
+ puts "Participants:"
21
+ room_info['participants'].each do |p|
22
+ puts p['name']
23
+ end
24
+ end
25
+
26
+ desc "users", "Show all users"
27
+ def users
28
+ client.users.sort do
29
+ |b,a| a['last_active'].to_i <=> b['last_active'].to_i
30
+ end.each do |u|
31
+ printf "%6s %-25s %-15s %-25s %-17s %-19s %s\n", u['user_id'], u['name'], u['mention_name'], u['email'], u['last_active'], u['timezone'], u['title']
32
+ end
33
+ end
34
+
35
+ desc "create ROOM", "Create a hipchat room"
36
+ def create( room )
37
+ puts "Creating room: #{room}"
38
+
39
+ client.create_room( room, "Let's talk about #{room}!" )
40
+
41
+ rooms
42
+ end
43
+
44
+ desc "topic ROOM TOPIC", "Set a topic of a hipchat room"
45
+ def topic( room, topic )
46
+ client.set_topic room, topic
47
+ end
48
+
49
+ desc "message ROOM MESSAGE", "Send a room a message"
50
+ def message( room, message )
51
+ client.post_message room, message
52
+ end
53
+
54
+ no_commands do
55
+ def client
56
+ @client ||= Blend::Client.hipchat_client
57
+ end
58
+ end
59
+ end
60
+ end
61
+ end