brasa 0.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 80e53e0d5fb933d533d94ab5863759651936979cf39b41bee334e2558e3fc343
4
- data.tar.gz: 3274b32a209a87202587d48a9acc8f25df7f05b6f59472805ebad6b0ed646971
3
+ metadata.gz: 9f7ecb8d9dafb1f7fe0e297323e2e0b5c4a9bbf2f8bf2b34145bceb5deea51f3
4
+ data.tar.gz: 03ea9501f89e932e79a4951fb109e00200f89583453c516939610cb3ea2be6c4
5
5
  SHA512:
6
- metadata.gz: 0ee91bdc2edea4b69d84a9d788b525f5275c5b0483055e8235bc201fb9308751df3e7697dcd6c9d423612d243431ff651d8d243aaf72ef5ad1561e37570d190e
7
- data.tar.gz: 55e7419b734c594a766e8e48ebc0ceba35a1ac83be0364b50f8d087b6a450b16fdfd4c461a0b8653d4d0174a25c2a69d17327ed959309905e8d29f8498a34b11
6
+ metadata.gz: e8cc452b7bbacacd245ab2de59944379c76b455ac9aa1a69adac55b7b5b955106eb6c38d5b77e4437ca177749c384d222a90863c90473c32c1c1ca4a44bbcd95
7
+ data.tar.gz: ff72d9f447707ed7dab625884ac8ddc759b3d6895cc1775578a99ce46f57877a1370c3c051ad09711710982deef9431382d70661625d6fa82ad06ac5c813c339
data/README.md CHANGED
@@ -58,7 +58,7 @@ stack: rails
58
58
 
59
59
  | Variavel | Descricao | Padrao |
60
60
  |----------|-----------|--------|
61
- | `BRASA_API_URL` | URL da API | `https://api.brasa.com.br` |
61
+ | `BRASA_API_URL` | URL da API | `https://api.usebrasa.com.br` |
62
62
 
63
63
  ## Licenca
64
64
 
data/lib/brasa/cli.rb CHANGED
@@ -4,12 +4,15 @@ 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"
10
12
  require "brasa/commands/status"
11
13
  require "brasa/commands/destroy"
12
14
  require "brasa/commands/domains"
15
+ require "brasa/commands/redis"
13
16
 
14
17
  module Brasa
15
18
  class CLI < Thor
@@ -44,6 +47,25 @@ module Brasa
44
47
  Commands::Logs.new.execute(options)
45
48
  end
46
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
+
47
69
  desc "env SUBCOMMAND", "Gerenciar variáveis de ambiente"
48
70
  subcommand "env", Commands::Env
49
71
 
@@ -53,6 +75,9 @@ module Brasa
53
75
  desc "domains SUBCOMMAND", "Gerenciar domínios customizados"
54
76
  subcommand "domains", Commands::Domains
55
77
 
78
+ desc "redis SUBCOMMAND", "Gerenciar Redis cache"
79
+ subcommand "redis", Commands::Redis
80
+
56
81
  desc "scale", "Escalar a aplicação"
57
82
  option :web, type: :numeric, desc: "Número de instâncias web"
58
83
  option :preset, type: :string, desc: "Preset (hobby, production, scale)"
@@ -37,7 +37,7 @@ module Brasa
37
37
  result = helper.api.post("/api/v1/apps/#{slug}/domains", body: { domain: { hostname: hostname } })
38
38
  helper.success("Domínio #{hostname} adicionado.")
39
39
  helper.info("Token de verificação: #{result["verification_token"]}")
40
- helper.info("Adicione um registro CNAME ou TXT apontando para #{slug}.brasa.com.br")
40
+ helper.info("Adicione um registro CNAME ou TXT apontando para #{slug}.usebrasa.com.br")
41
41
  rescue Api::Client::ValidationError => e
42
42
  DomainsHelper.new.error("Erro: #{e.message}")
43
43
  rescue Api::Client::ApiError => e
@@ -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
@@ -0,0 +1,74 @@
1
+ require "thor"
2
+ require "brasa/commands/base"
3
+
4
+ module Brasa
5
+ module Commands
6
+ class Redis < Thor
7
+ namespace :redis
8
+
9
+ MEMORY_TO_PLAN = {
10
+ 256 => "starter",
11
+ 512 => "pro",
12
+ 1024 => "business"
13
+ }.freeze
14
+
15
+ desc "status", "Ver status do Redis"
16
+ def status
17
+ helper = RedisHelper.new
18
+ helper.require_auth!
19
+ slug = helper.app_slug
20
+
21
+ addon = helper.api.get("/api/v1/apps/#{slug}/addons/cache")
22
+
23
+ puts helper.pastel.bold("Redis de #{slug}")
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"
28
+ rescue Api::Client::ApiError => e
29
+ RedisHelper.new.error("Erro: #{e.message}")
30
+ end
31
+
32
+ desc "enable", "Habilitar Redis para o app"
33
+ option :memory, type: :numeric, default: 256, desc: "Memória em MB (256, 512, 1024)"
34
+ def enable
35
+ helper = RedisHelper.new
36
+ helper.require_auth!
37
+ slug = helper.app_slug
38
+
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 } })
47
+ helper.success("Redis habilitado! Status: #{result["status"]}")
48
+ rescue Api::Client::ApiError => e
49
+ RedisHelper.new.error("Erro: #{e.message}")
50
+ end
51
+
52
+ desc "disable", "Remover Redis do app"
53
+ def disable
54
+ helper = RedisHelper.new
55
+ helper.require_auth!
56
+ slug = helper.app_slug
57
+
58
+ prompt = TTY::Prompt.new
59
+ unless prompt.yes?("Remover Redis? Todos os dados em cache serão perdidos.")
60
+ helper.info("Operação cancelada.")
61
+ return
62
+ end
63
+
64
+ helper.info("Removendo Redis...")
65
+ helper.api.delete("/api/v1/apps/#{slug}/addons/cache")
66
+ helper.success("Redis removido com sucesso!")
67
+ rescue Api::Client::ApiError => e
68
+ RedisHelper.new.error("Erro: #{e.message}")
69
+ end
70
+ end
71
+
72
+ class RedisHelper < Base; end
73
+ end
74
+ end
@@ -15,7 +15,7 @@ module Brasa
15
15
  puts " Status: #{colorize_status(app["status"])}"
16
16
  puts " Região: #{app["region"]}"
17
17
  puts " Preset: #{app["preset"]}"
18
- puts " URL: https://#{app["slug"]}.brasa.com.br"
18
+ puts " URL: https://#{app["slug"]}.usebrasa.com.br"
19
19
 
20
20
  if app["last_deploy"]
21
21
  deploy = app["last_deploy"]
@@ -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
- success("Deploy concluído! App disponível em https://#{app["slug"]}.brasa.com.br")
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/config.rb CHANGED
@@ -7,7 +7,7 @@ module Brasa
7
7
  CREDENTIALS_FILE = File.join(CONFIG_DIR, "credentials.json").freeze
8
8
  PROJECT_FILE = ".brasa.yml".freeze
9
9
 
10
- DEFAULT_API_URL = "https://api.brasa.com.br".freeze
10
+ DEFAULT_API_URL = "https://api.usebrasa.com.br".freeze
11
11
 
12
12
  class << self
13
13
  def api_url
data/lib/brasa/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Brasa
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.1"
3
3
  end
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.1.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brasa
@@ -124,7 +124,7 @@ dependencies:
124
124
  description: Deploy apps Rails e Node.js na nuvem brasileira com um comando. Soberania
125
125
  de dados, faturamento em reais.
126
126
  email:
127
- - contato@brasa.com.br
127
+ - contato@usebrasa.com.br
128
128
  executables:
129
129
  - brasa
130
130
  extensions: []
@@ -145,12 +145,15 @@ 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
150
+ - lib/brasa/commands/redis.rb
148
151
  - lib/brasa/commands/scale.rb
149
152
  - lib/brasa/commands/status.rb
150
153
  - lib/brasa/commands/up.rb
151
154
  - lib/brasa/config.rb
152
155
  - lib/brasa/version.rb
153
- homepage: https://brasa.com.br
156
+ homepage: https://usebrasa.com.br
154
157
  licenses:
155
158
  - MIT
156
159
  metadata: {}