brasa 0.2.0 → 0.2.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.
- checksums.yaml +4 -4
- data/lib/brasa/cli.rb +21 -0
- data/lib/brasa/commands/logs_export.rb +28 -0
- data/lib/brasa/commands/logs_search.rb +47 -0
- data/lib/brasa/commands/redis.rb +20 -8
- data/lib/brasa/commands/up.rb +12 -7
- data/lib/brasa/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9f7ecb8d9dafb1f7fe0e297323e2e0b5c4a9bbf2f8bf2b34145bceb5deea51f3
|
|
4
|
+
data.tar.gz: 03ea9501f89e932e79a4951fb109e00200f89583453c516939610cb3ea2be6c4
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: e8cc452b7bbacacd245ab2de59944379c76b455ac9aa1a69adac55b7b5b955106eb6c38d5b77e4437ca177749c384d222a90863c90473c32c1c1ca4a44bbcd95
|
|
7
|
+
data.tar.gz: ff72d9f447707ed7dab625884ac8ddc759b3d6895cc1775578a99ce46f57877a1370c3c051ad09711710982deef9431382d70661625d6fa82ad06ac5c813c339
|
data/lib/brasa/cli.rb
CHANGED
|
@@ -4,6 +4,8 @@ require "brasa/commands/init"
|
|
|
4
4
|
require "brasa/commands/up"
|
|
5
5
|
require "brasa/commands/deploy"
|
|
6
6
|
require "brasa/commands/logs"
|
|
7
|
+
require "brasa/commands/logs_search"
|
|
8
|
+
require "brasa/commands/logs_export"
|
|
7
9
|
require "brasa/commands/env"
|
|
8
10
|
require "brasa/commands/database"
|
|
9
11
|
require "brasa/commands/scale"
|
|
@@ -45,6 +47,25 @@ module Brasa
|
|
|
45
47
|
Commands::Logs.new.execute(options)
|
|
46
48
|
end
|
|
47
49
|
|
|
50
|
+
desc "logs:search", "Buscar nos logs da aplicação"
|
|
51
|
+
option :query, type: :string, required: true, desc: "Termo de busca"
|
|
52
|
+
option :level, type: :string, desc: "Filtrar por nível (error, warn, info)"
|
|
53
|
+
option :source, type: :string, desc: "Filtrar por source"
|
|
54
|
+
option :since, type: :string, desc: "Período (ex: 1h, 24h, 7d)"
|
|
55
|
+
option :limit, type: :string, default: "100", desc: "Limite de resultados"
|
|
56
|
+
define_method("logs:search") do
|
|
57
|
+
Commands::LogsSearch.new.execute(options)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
desc "logs:export", "Exportar logs da aplicação"
|
|
61
|
+
option :format, type: :string, default: "json", desc: "Formato de exportação (json, csv)"
|
|
62
|
+
option :since, type: :string, desc: "Data/hora inicial"
|
|
63
|
+
option :until, type: :string, desc: "Data/hora final"
|
|
64
|
+
option :level, type: :string, desc: "Filtrar por nível (error, warn, info)"
|
|
65
|
+
define_method("logs:export") do
|
|
66
|
+
Commands::LogsExport.new.execute(options)
|
|
67
|
+
end
|
|
68
|
+
|
|
48
69
|
desc "env SUBCOMMAND", "Gerenciar variáveis de ambiente"
|
|
49
70
|
subcommand "env", Commands::Env
|
|
50
71
|
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
require "brasa/commands/base"
|
|
2
|
+
|
|
3
|
+
module Brasa
|
|
4
|
+
module Commands
|
|
5
|
+
class LogsExport < Base
|
|
6
|
+
def execute(options = {})
|
|
7
|
+
require_auth!
|
|
8
|
+
slug = app_slug
|
|
9
|
+
|
|
10
|
+
format = options.fetch("format", "json")
|
|
11
|
+
params = { export_format: format }
|
|
12
|
+
params[:since] = options["since"] if options["since"]
|
|
13
|
+
params[:until] = options["until"] if options["until"]
|
|
14
|
+
params[:level] = options["level"] if options["level"]
|
|
15
|
+
|
|
16
|
+
result = api.get("/api/v1/apps/#{slug}/logs/export", params: params)
|
|
17
|
+
|
|
18
|
+
if result.is_a?(Array)
|
|
19
|
+
puts JSON.pretty_generate(result)
|
|
20
|
+
else
|
|
21
|
+
puts result
|
|
22
|
+
end
|
|
23
|
+
rescue Api::Client::ApiError => e
|
|
24
|
+
error("Erro: #{e.message}")
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
require "brasa/commands/base"
|
|
2
|
+
|
|
3
|
+
module Brasa
|
|
4
|
+
module Commands
|
|
5
|
+
class LogsSearch < Base
|
|
6
|
+
def execute(options = {})
|
|
7
|
+
require_auth!
|
|
8
|
+
slug = app_slug
|
|
9
|
+
query = options["query"]
|
|
10
|
+
|
|
11
|
+
unless query
|
|
12
|
+
info("Uso: brasa logs:search <query> [--level error] [--since 1h]")
|
|
13
|
+
return
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
params = { q: query, limit: options.fetch("limit", "100") }
|
|
17
|
+
params[:level] = options["level"] if options["level"]
|
|
18
|
+
params[:source] = options["source"] if options["source"]
|
|
19
|
+
params[:since] = options["since"] if options["since"]
|
|
20
|
+
|
|
21
|
+
results = api.get("/api/v1/apps/#{slug}/logs/search", params: params)
|
|
22
|
+
|
|
23
|
+
if results.nil? || results.empty?
|
|
24
|
+
info("Nenhum resultado encontrado.")
|
|
25
|
+
return
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
results.each do |entry|
|
|
29
|
+
puts "#{pastel.dim(entry["timestamp"])} #{pastel.cyan(entry["source"])} [#{colorize_level(entry["level"])}] #{entry["message"]}"
|
|
30
|
+
end
|
|
31
|
+
rescue Api::Client::ApiError => e
|
|
32
|
+
error("Erro: #{e.message}")
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
private
|
|
36
|
+
|
|
37
|
+
def colorize_level(level)
|
|
38
|
+
case level
|
|
39
|
+
when "error" then pastel.red(level)
|
|
40
|
+
when "warn" then pastel.yellow(level)
|
|
41
|
+
when "info" then pastel.green(level)
|
|
42
|
+
else pastel.dim(level)
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/brasa/commands/redis.rb
CHANGED
|
@@ -6,19 +6,25 @@ module Brasa
|
|
|
6
6
|
class Redis < Thor
|
|
7
7
|
namespace :redis
|
|
8
8
|
|
|
9
|
+
MEMORY_TO_PLAN = {
|
|
10
|
+
256 => "starter",
|
|
11
|
+
512 => "pro",
|
|
12
|
+
1024 => "business"
|
|
13
|
+
}.freeze
|
|
14
|
+
|
|
9
15
|
desc "status", "Ver status do Redis"
|
|
10
16
|
def status
|
|
11
17
|
helper = RedisHelper.new
|
|
12
18
|
helper.require_auth!
|
|
13
19
|
slug = helper.app_slug
|
|
14
20
|
|
|
15
|
-
|
|
21
|
+
addon = helper.api.get("/api/v1/apps/#{slug}/addons/cache")
|
|
16
22
|
|
|
17
23
|
puts helper.pastel.bold("Redis de #{slug}")
|
|
18
|
-
puts " Status: #{
|
|
19
|
-
puts "
|
|
20
|
-
puts " Memória: #{
|
|
21
|
-
puts "
|
|
24
|
+
puts " Status: #{addon["status"]}"
|
|
25
|
+
puts " Plano: #{addon["plan"]}"
|
|
26
|
+
puts " Memória: #{addon.dig("config", "memory_mb")}MB"
|
|
27
|
+
puts " Custo: R$ #{addon["monthly_cost_brl"]}/mês"
|
|
22
28
|
rescue Api::Client::ApiError => e
|
|
23
29
|
RedisHelper.new.error("Erro: #{e.message}")
|
|
24
30
|
end
|
|
@@ -30,8 +36,14 @@ module Brasa
|
|
|
30
36
|
helper.require_auth!
|
|
31
37
|
slug = helper.app_slug
|
|
32
38
|
|
|
33
|
-
|
|
34
|
-
|
|
39
|
+
plan = MEMORY_TO_PLAN[options[:memory]]
|
|
40
|
+
unless plan
|
|
41
|
+
helper.error("Memória inválida. Use: 256, 512 ou 1024")
|
|
42
|
+
return
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
helper.info("Habilitando Redis com #{options[:memory]}MB (plano #{plan})...")
|
|
46
|
+
result = helper.api.post("/api/v1/apps/#{slug}/addons", { addon: { slug: "cache", plan: plan } })
|
|
35
47
|
helper.success("Redis habilitado! Status: #{result["status"]}")
|
|
36
48
|
rescue Api::Client::ApiError => e
|
|
37
49
|
RedisHelper.new.error("Erro: #{e.message}")
|
|
@@ -50,7 +62,7 @@ module Brasa
|
|
|
50
62
|
end
|
|
51
63
|
|
|
52
64
|
helper.info("Removendo Redis...")
|
|
53
|
-
helper.api.delete("/api/v1/apps/#{slug}/
|
|
65
|
+
helper.api.delete("/api/v1/apps/#{slug}/addons/cache")
|
|
54
66
|
helper.success("Redis removido com sucesso!")
|
|
55
67
|
rescue Api::Client::ApiError => e
|
|
56
68
|
RedisHelper.new.error("Erro: #{e.message}")
|
data/lib/brasa/commands/up.rb
CHANGED
|
@@ -15,14 +15,17 @@ module Brasa
|
|
|
15
15
|
app = create_app(config)
|
|
16
16
|
info("App #{app["slug"]} criado. Provisionando infraestrutura...")
|
|
17
17
|
|
|
18
|
-
wait_for_provisioning(app["slug"])
|
|
18
|
+
unless wait_for_provisioning(app["slug"])
|
|
19
|
+
return
|
|
20
|
+
end
|
|
19
21
|
success("Infraestrutura provisionada!")
|
|
20
22
|
|
|
21
23
|
info("Iniciando primeiro deploy...")
|
|
22
24
|
deploy = trigger_deploy(app["slug"])
|
|
23
|
-
wait_for_deploy(app["slug"], deploy["id"])
|
|
24
25
|
|
|
25
|
-
|
|
26
|
+
if wait_for_deploy(app["slug"], deploy["id"])
|
|
27
|
+
success("Deploy concluído! App disponível em https://#{app["slug"]}.usebrasa.com.br")
|
|
28
|
+
end
|
|
26
29
|
rescue Api::Client::ValidationError => e
|
|
27
30
|
error("Erro ao criar app: #{e.message}")
|
|
28
31
|
rescue Api::Client::ApiError => e
|
|
@@ -48,29 +51,31 @@ module Brasa
|
|
|
48
51
|
def wait_for_provisioning(slug)
|
|
49
52
|
MAX_POLLS.times do
|
|
50
53
|
app = api.get("/api/v1/apps/#{slug}")
|
|
51
|
-
return if app["status"] == "active"
|
|
54
|
+
return true if app["status"] == "active"
|
|
52
55
|
if app["status"] == "error"
|
|
53
56
|
error("Erro no provisionamento.")
|
|
54
|
-
return
|
|
57
|
+
return false
|
|
55
58
|
end
|
|
56
59
|
print "."
|
|
57
60
|
sleep(POLL_INTERVAL)
|
|
58
61
|
end
|
|
59
62
|
error("Timeout aguardando provisionamento.")
|
|
63
|
+
false
|
|
60
64
|
end
|
|
61
65
|
|
|
62
66
|
def wait_for_deploy(slug, deploy_id)
|
|
63
67
|
MAX_POLLS.times do
|
|
64
68
|
deploy = api.get("/api/v1/apps/#{slug}/deploys/#{deploy_id}")
|
|
65
|
-
return if deploy["status"] == "live"
|
|
69
|
+
return true if deploy["status"] == "live"
|
|
66
70
|
if deploy["status"] == "failed"
|
|
67
71
|
error("Deploy falhou.")
|
|
68
|
-
return
|
|
72
|
+
return false
|
|
69
73
|
end
|
|
70
74
|
print "."
|
|
71
75
|
sleep(POLL_INTERVAL)
|
|
72
76
|
end
|
|
73
77
|
error("Timeout aguardando deploy.")
|
|
78
|
+
false
|
|
74
79
|
end
|
|
75
80
|
end
|
|
76
81
|
end
|
data/lib/brasa/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: brasa
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Brasa
|
|
@@ -145,6 +145,8 @@ files:
|
|
|
145
145
|
- lib/brasa/commands/init.rb
|
|
146
146
|
- lib/brasa/commands/login.rb
|
|
147
147
|
- lib/brasa/commands/logs.rb
|
|
148
|
+
- lib/brasa/commands/logs_export.rb
|
|
149
|
+
- lib/brasa/commands/logs_search.rb
|
|
148
150
|
- lib/brasa/commands/redis.rb
|
|
149
151
|
- lib/brasa/commands/scale.rb
|
|
150
152
|
- lib/brasa/commands/status.rb
|