tayo 0.2.0 → 0.2.2

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: b5fa91902d5a43f2bd8259bdd3949017b629c6f228cf68600f9b4fd238a13299
4
- data.tar.gz: 66e296458abdfca8cebf3e919be4f36f06fcbb1238cefd2e441d96cc193fcdda
3
+ metadata.gz: d2af6b108a756159090d922a64ba1e159590c4b0d0a17978c67a14794828f147
4
+ data.tar.gz: ef4333b8b9094ab0e040c330338cc61eaa4c9f13ea52a6cfc19354d7d3fcd92d
5
5
  SHA512:
6
- metadata.gz: 876880104575214b91231682c947c40a73ea233dd558644bb5d34d75e90e5b4a6046185e9e650c9a945d5d9e3d4fd77cc29a4fefbabb83d1c1f82683d2b5ce9b
7
- data.tar.gz: 2955f65d56f1395e823b159cc64fd2285dfe523dae26b21ea2aa896b350c499029d9fe84908fdbfad0ffbc50734e309386f1ef2613517f087c7499205d06dc36
6
+ metadata.gz: 4ae8aa7b218f16d90aec6ed99d7a0ee96884dd84b033faf6d359811c9d7105ea4ffc224d11093d626a207d6be15dc89b8eed74ae51c3991ff107ae263c851fcc
7
+ data.tar.gz: d6759cafa8c5c33ea27ab65c736109bb4575d2a9f658adbea2dec7b9a5f0ed827ed3e760a7f21581dca55767e73c7a33a5f0308bf68f90fe2619090a9e1315a4
@@ -12,61 +12,78 @@ module Tayo
12
12
  def execute
13
13
  puts "☁️ Cloudflare DNS 설정을 시작합니다...".colorize(:green)
14
14
 
15
- unless rails_project?
16
- puts "❌ Rails 프로젝트가 아닙니다. Rails 프로젝트 루트에서 실행해주세요.".colorize(:red)
17
- return
18
- end
19
-
20
- # 1. 도메인 입력받기
21
- domain_info = get_domain_input
22
-
23
- # 2. Cloudflare 토큰 생성 페이지 열기 및 권한 안내
15
+ # 1. Cloudflare 토큰 생성 페이지 열기 및 권한 안내
24
16
  open_token_creation_page
25
-
26
- # 3. 토큰 입력받기
17
+
18
+ # 2. 토큰 입력받기
27
19
  token = get_cloudflare_token
28
-
29
- # 4. Cloudflare API로 도메인 목록 조회 및 선택
20
+
21
+ # 3. Cloudflare API로 도메인 목록 조회 및 선택
30
22
  selected_zone = select_cloudflare_zone(token)
31
-
32
- # 5. 루트 도메인 레코드 확인
33
- existing_records = check_existing_records(token, selected_zone, domain_info)
34
-
35
- # 6. DNS 레코드 추가/수정
36
- setup_dns_record(token, selected_zone, domain_info, existing_records)
37
-
38
- # 7. config/deploy.yml 업데이트
39
- update_deploy_config(domain_info)
23
+
24
+ # 4. 기존 레코드 목록 표시
25
+ show_existing_records(token, selected_zone)
26
+
27
+ # 5. 서비스 도메인 입력받기
28
+ domain_info = get_domain_input(selected_zone)
29
+
30
+ # 6. 홈서버 연결 정보 입력받기
31
+ server_info = get_server_info
32
+
33
+ # 7. DNS 레코드 추가/수정
34
+ setup_dns_record(token, selected_zone, domain_info, server_info)
35
+
36
+ # 8. config/deploy.yml 업데이트
37
+ update_deploy_config(domain_info, server_info)
40
38
 
41
39
  puts "\n🎉 Cloudflare DNS 설정이 완료되었습니다!".colorize(:green)
42
-
40
+
43
41
  # 변경사항 커밋
44
42
  commit_cloudflare_changes(domain_info)
45
43
  end
46
44
 
47
45
  private
48
46
 
49
- def rails_project?
50
- File.exist?("Gemfile") && File.exist?("config/application.rb")
47
+ def get_domain_input(zone)
48
+ prompt = TTY::Prompt.new
49
+ zone_name = zone['name']
50
+
51
+ puts "📝 서비스 도메인을 설정합니다.".colorize(:yellow)
52
+ puts " 선택된 Zone: #{zone_name}".colorize(:gray)
53
+
54
+ use_subdomain = prompt.yes?("서브도메인을 사용하시겠습니까? (예: app.#{zone_name})")
55
+
56
+ if use_subdomain
57
+ subdomain = prompt.ask("서브도메인을 입력하세요 (예: app, api, www):") do |q|
58
+ q.validate(/\A[a-zA-Z0-9-]+\z/, "올바른 서브도메인을 입력해주세요 (영문, 숫자, 하이픈만 가능)")
59
+ end
60
+ full_domain = "#{subdomain}.#{zone_name}"
61
+ { type: :subdomain, domain: full_domain, zone: zone_name, subdomain: subdomain }
62
+ else
63
+ { type: :root, domain: zone_name, zone: zone_name }
64
+ end
51
65
  end
52
66
 
53
- def get_domain_input
67
+ def get_server_info
54
68
  prompt = TTY::Prompt.new
55
-
56
- puts "\n📝 배포할 도메인을 설정합니다.".colorize(:yellow)
57
-
58
- domain = prompt.ask("배포할 도메인을 입력하세요 (예: myapp.com, api.example.com):") do |q|
59
- q.validate(/\A[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\z/, "올바른 도메인 형식을 입력해주세요 (예: myapp.com)")
60
- end
61
-
62
- # 도메인이 루트인지 서브도메인인지 판단
63
- parts = domain.split('.')
64
- if parts.length == 2
65
- { type: :root, domain: domain, zone: domain }
66
- else
67
- zone = parts[-2..-1].join('.')
68
- { type: :subdomain, domain: domain, zone: zone, subdomain: parts[0..-3].join('.') }
69
+
70
+ puts "\n🖥️ 홈서버 연결 정보를 입력합니다.".colorize(:yellow)
71
+
72
+ server_address = prompt.ask("홈서버 IP 또는 도메인을 입력하세요:") do |q|
73
+ q.validate(/\A.+\z/, "서버 정보를 입력해주세요")
69
74
  end
75
+
76
+ ssh_user = prompt.ask("SSH 사용자 계정을 입력하세요:", default: "root")
77
+
78
+ # IP인지 도메인인지 판단
79
+ is_ip = server_address.match?(/\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/)
80
+ record_type = is_ip ? 'A' : 'CNAME'
81
+
82
+ {
83
+ address: server_address,
84
+ ssh_user: ssh_user,
85
+ record_type: record_type
86
+ }
70
87
  end
71
88
 
72
89
  def open_token_creation_page
@@ -79,12 +96,10 @@ module Tayo
79
96
  puts "\n다음 권한으로 토큰을 생성해주세요:".colorize(:yellow)
80
97
  puts ""
81
98
  puts "한국어 화면:".colorize(:gray)
82
- puts "• 영역 → DNS → 읽기".colorize(:white)
83
99
  puts "• 영역 → DNS → 편집".colorize(:white)
84
100
  puts " (영역 리소스는 '모든 영역' 선택)".colorize(:gray)
85
101
  puts ""
86
102
  puts "English:".colorize(:gray)
87
- puts "• Zone → DNS → Read".colorize(:white)
88
103
  puts "• Zone → DNS → Edit".colorize(:white)
89
104
  puts " (Zone Resources: Select 'All zones')".colorize(:gray)
90
105
  puts ""
@@ -171,18 +186,53 @@ module Tayo
171
186
  exit 1
172
187
  end
173
188
 
174
- def check_existing_records(token, zone, domain_info)
189
+ def show_existing_records(token, zone)
175
190
  puts "\n🔍 기존 DNS 레코드를 확인합니다...".colorize(:yellow)
176
-
191
+
177
192
  zone_id = zone['id']
178
193
  zone_name = zone['name']
179
-
180
- # 루트 도메인의 A/CNAME 레코드 확인
181
- records = get_dns_records(token, zone_id, zone_name, ['A', 'CNAME'])
182
-
183
- puts "기존 레코드: #{records.length}개 발견".colorize(:gray)
184
-
185
- return records
194
+
195
+ # Zone의 모든 A/CNAME 레코드 조회
196
+ records = get_all_dns_records(token, zone_id, ['A', 'CNAME'])
197
+
198
+ if records.empty?
199
+ puts " 등록된 A/CNAME 레코드가 없습니다.".colorize(:gray)
200
+ else
201
+ puts " #{zone_name}의 기존 레코드:".colorize(:cyan)
202
+ records.each do |record|
203
+ puts " • #{record['name']} → #{record['content']} (#{record['type']})".colorize(:white)
204
+ end
205
+ end
206
+
207
+ puts ""
208
+ end
209
+
210
+ def get_all_dns_records(token, zone_id, types)
211
+ records = []
212
+
213
+ types.each do |type|
214
+ uri = URI("https://api.cloudflare.com/client/v4/zones/#{zone_id}/dns_records")
215
+ uri.query = URI.encode_www_form({ type: type })
216
+
217
+ http = Net::HTTP.new(uri.host, uri.port)
218
+ http.use_ssl = true
219
+
220
+ request = Net::HTTP::Get.new(uri)
221
+ request['Authorization'] = "Bearer #{token}"
222
+ request['Content-Type'] = 'application/json'
223
+
224
+ response = http.request(request)
225
+
226
+ if response.code == '200'
227
+ data = JSON.parse(response.body)
228
+ records.concat(data['result'] || [])
229
+ end
230
+ end
231
+
232
+ records.sort_by { |r| r['name'] }
233
+ rescue => e
234
+ puts "⚠️ DNS 레코드 조회 중 오류: #{e.message}".colorize(:yellow)
235
+ []
186
236
  end
187
237
 
188
238
  def get_dns_records(token, zone_id, name, types)
@@ -216,73 +266,41 @@ module Tayo
216
266
  return []
217
267
  end
218
268
 
219
- def setup_dns_record(token, zone, domain_info, existing_records)
269
+ def setup_dns_record(token, zone, domain_info, server_info)
220
270
  puts "\n⚙️ DNS 레코드를 설정합니다...".colorize(:yellow)
221
-
222
- # 홈서버 IP/URL 입력받기
223
- prompt = TTY::Prompt.new
224
-
225
- server_info = prompt.ask("홈서버 IP 또는 도메인을 입력하세요:") do |q|
226
- q.validate(/\A.+\z/, "서버 정보를 입력해주세요")
227
- end
228
-
229
- # SSH 사용자 계정 입력받기
230
- ssh_user = prompt.ask("SSH 사용자 계정을 입력하세요:", default: "root")
231
-
232
- # IP인지 도메인인지 판단
233
- is_ip = server_info.match?(/\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/)
234
- record_type = is_ip ? 'A' : 'CNAME'
235
-
271
+
236
272
  zone_id = zone['id']
237
- zone_name = zone['name']
238
-
239
- # 도메인 정보에 따라 레코드 설정
240
- final_domain = determine_final_domain(domain_info, zone_name, existing_records)
241
-
242
- # 대상 도메인의 모든 A/CNAME 레코드 확인
243
- all_records = get_dns_records(token, zone_id, final_domain[:name], ['A', 'CNAME'])
244
-
245
- if all_records.any?
246
- existing_record = all_records.first
247
-
273
+ target_domain = domain_info[:domain]
274
+ server_address = server_info[:address]
275
+ record_type = server_info[:record_type]
276
+
277
+ # 대상 도메인의 기존 A/CNAME 레코드 확인
278
+ existing_records = get_dns_records(token, zone_id, target_domain, ['A', 'CNAME'])
279
+
280
+ if existing_records.any?
281
+ existing_record = existing_records.first
282
+
248
283
  # 동일한 타입이고 같은 값이면 건너뛰기
249
- if existing_record['type'] == record_type && existing_record['content'] == server_info
284
+ if existing_record['type'] == record_type && existing_record['content'] == server_address
250
285
  puts "✅ DNS 레코드가 이미 올바르게 설정되어 있습니다.".colorize(:green)
251
- puts " #{final_domain[:full_domain]} → #{server_info} (#{record_type} 레코드)".colorize(:gray)
286
+ puts " #{target_domain} → #{server_address} (#{record_type} 레코드)".colorize(:gray)
252
287
  else
253
288
  # 타입이 다르거나 값이 다른 경우 삭제 후 재생성
254
289
  puts "⚠️ 기존 레코드를 삭제하고 새로 생성합니다.".colorize(:yellow)
255
- puts " 기존: #{existing_record['content']} (#{existing_record['type']}) → 새로운: #{server_info} (#{record_type})".colorize(:gray)
256
-
290
+ puts " 기존: #{existing_record['content']} (#{existing_record['type']}) → 새로운: #{server_address} (#{record_type})".colorize(:gray)
291
+
257
292
  # 기존 레코드 삭제
258
293
  delete_dns_record(token, zone_id, existing_record['id'])
259
-
294
+
260
295
  # 새 레코드 생성
261
- create_dns_record(token, zone_id, final_domain[:name], record_type, server_info)
296
+ create_dns_record(token, zone_id, target_domain, record_type, server_address)
262
297
  end
263
298
  else
264
299
  # DNS 레코드 생성
265
- create_dns_record(token, zone_id, final_domain[:name], record_type, server_info)
300
+ create_dns_record(token, zone_id, target_domain, record_type, server_address)
266
301
  end
267
-
268
- # 최종 도메인 정보 저장
269
- @final_domain = final_domain[:full_domain]
270
- @server_info = server_info
271
- @ssh_user = ssh_user
272
- end
273
302
 
274
- def determine_final_domain(domain_info, zone_name, existing_records)
275
- case domain_info[:type]
276
- when :root
277
- if existing_records.any?
278
- puts "⚠️ 루트 도메인에 이미 레코드가 있습니다. app.#{zone_name}을 사용합니다.".colorize(:yellow)
279
- { name: "app.#{zone_name}", full_domain: "app.#{zone_name}" }
280
- else
281
- { name: zone_name, full_domain: zone_name }
282
- end
283
- when :subdomain
284
- { name: domain_info[:domain], full_domain: domain_info[:domain] }
285
- end
303
+ puts " #{target_domain} #{server_address}".colorize(:cyan)
286
304
  end
287
305
 
288
306
  def create_dns_record(token, zone_id, name, type, content)
@@ -340,53 +358,56 @@ module Tayo
340
358
  exit 1
341
359
  end
342
360
 
343
- def update_deploy_config(domain_info)
361
+ def update_deploy_config(domain_info, server_info)
344
362
  puts "\n📝 배포 설정을 업데이트합니다...".colorize(:yellow)
345
-
363
+
346
364
  config_file = "config/deploy.yml"
347
-
365
+ final_domain = domain_info[:domain]
366
+ server_address = server_info[:address]
367
+ ssh_user = server_info[:ssh_user]
368
+
348
369
  unless File.exist?(config_file)
349
370
  puts "⚠️ config/deploy.yml 파일이 없습니다.".colorize(:yellow)
350
371
  return
351
372
  end
352
-
373
+
353
374
  content = File.read(config_file)
354
-
375
+
355
376
  # proxy.host 설정 업데이트
356
377
  if content.include?("proxy:")
357
- content.gsub!(/(\s+host:\s+).*$/, "\\1#{@final_domain}")
378
+ content.gsub!(/(\s+host:\s+).*$/, "\\1#{final_domain}")
358
379
  else
359
380
  # proxy 섹션이 없으면 추가
360
- proxy_config = "\n# Proxy configuration\nproxy:\n ssl: true\n host: #{@final_domain}\n"
381
+ proxy_config = "\n# Proxy configuration\nproxy:\n ssl: true\n host: #{final_domain}\n"
361
382
  content += proxy_config
362
383
  end
363
-
384
+
364
385
  # servers 설정 업데이트
365
386
  if content.match?(/servers:\s*\n\s*web:\s*\n\s*-\s*/)
366
- content.gsub!(/(\s*servers:\s*\n\s*web:\s*\n\s*-\s*)[\d.]+/, "\\1#{@server_info}")
387
+ content.gsub!(/(\s*servers:\s*\n\s*web:\s*\n\s*-\s*)[\d.]+/, "\\1#{server_address}")
367
388
  end
368
-
389
+
369
390
  # ssh user 설정 업데이트
370
- if @ssh_user && @ssh_user != "root"
391
+ if ssh_user && ssh_user != "root"
371
392
  if content.match?(/^ssh:/)
372
393
  # 기존 ssh 섹션 업데이트
373
- content.gsub!(/^ssh:\s*\n\s*user:\s*\w+/, "ssh:\n user: #{@ssh_user}")
394
+ content.gsub!(/^ssh:\s*\n\s*user:\s*\w+/, "ssh:\n user: #{ssh_user}")
374
395
  else
375
396
  # ssh 섹션 추가 (accessories 섹션 앞에 추가)
376
397
  if content.match?(/^# Use accessory services/)
377
- content.gsub!(/^# Use accessory services/, "# Use a different ssh user than root\nssh:\n user: #{@ssh_user}\n\n# Use accessory services")
398
+ content.gsub!(/^# Use accessory services/, "# Use a different ssh user than root\nssh:\n user: #{ssh_user}\n\n# Use accessory services")
378
399
  else
379
400
  # 파일 끝에 추가
380
- content += "\n# Use a different ssh user than root\nssh:\n user: #{@ssh_user}\n"
401
+ content += "\n# Use a different ssh user than root\nssh:\n user: #{ssh_user}\n"
381
402
  end
382
403
  end
383
404
  end
384
-
405
+
385
406
  File.write(config_file, content)
386
407
  puts "✅ config/deploy.yml이 업데이트되었습니다.".colorize(:green)
387
- puts " proxy.host: #{@final_domain}".colorize(:gray)
388
- puts " servers.web: #{@server_info}".colorize(:gray)
389
- puts " ssh.user: #{@ssh_user}".colorize(:gray) if @ssh_user && @ssh_user != "root"
408
+ puts " proxy.host: #{final_domain}".colorize(:gray)
409
+ puts " servers.web: #{server_address}".colorize(:gray)
410
+ puts " ssh.user: #{ssh_user}".colorize(:gray) if ssh_user && ssh_user != "root"
390
411
  end
391
412
 
392
413
  def commit_cloudflare_changes(domain_info)
@@ -12,11 +12,6 @@ module Tayo
12
12
  def execute
13
13
  puts "🚀 GitHub 저장소 및 컨테이너 레지스트리 설정을 시작합니다...".colorize(:green)
14
14
 
15
- unless rails_project?
16
- puts "❌ Rails 프로젝트가 아닙니다. Rails 프로젝트 루트에서 실행해주세요.".colorize(:red)
17
- return
18
- end
19
-
20
15
  puts "\n[1/7] GitHub CLI 설치 확인".colorize(:blue)
21
16
  check_github_cli
22
17
 
@@ -50,10 +45,6 @@ module Tayo
50
45
 
51
46
  private
52
47
 
53
- def rails_project?
54
- File.exist?("Gemfile") && File.exist?("config/application.rb")
55
- end
56
-
57
48
  def check_github_cli
58
49
  if system("gh --version", out: File::NULL, err: File::NULL)
59
50
  puts "✅ GitHub CLI가 이미 설치되어 있습니다.".colorize(:green)
data/lib/tayo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Tayo
4
- VERSION = "0.2.0"
4
+ VERSION = "0.2.2"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tayo
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - 이원섭wonsup Lee/Alfonso