tayo 0.1.13 → 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.
@@ -12,129 +12,100 @@ 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
15
+ # 1. Cloudflare 토큰 생성 페이지 열기 및 권한 안내
16
+ open_token_creation_page
19
17
 
20
- # --- 로직 순서 변경 ---
21
-
22
18
  # 2. 토큰 입력받기
23
19
  token = get_cloudflare_token
24
-
25
- # 3. Cloudflare 존 선택 및 도메인 구성 (새로운 방식)
26
- domain_info = configure_domain_from_zones(token)
27
- selected_zone = domain_info[:selected_zone_object]
28
20
 
29
- # 4. 기존 DNS 레코드 확인 (참고용)
30
- existing_records = check_existing_records(token, selected_zone, domain_info)
31
-
32
- # 5. DNS 레코드 추가/수정 (루트 도메인 덮어쓰기 로직 포함)
33
- setup_dns_record(token, selected_zone, domain_info, existing_records)
34
-
35
- # 6. config/deploy.yml 업데이트
36
- update_deploy_config(domain_info)
21
+ # 3. Cloudflare API로 도메인 목록 조회 및 선택
22
+ selected_zone = select_cloudflare_zone(token)
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)
37
38
 
38
39
  puts "\n🎉 Cloudflare DNS 설정이 완료되었습니다!".colorize(:green)
39
-
40
- # 7. 변경사항 커밋
40
+
41
+ # 변경사항 커밋
41
42
  commit_cloudflare_changes(domain_info)
42
43
  end
43
44
 
44
45
  private
45
46
 
46
- def rails_project?
47
- File.exist?("Gemfile") && File.exist?("config/application.rb")
48
- end
47
+ def get_domain_input(zone)
48
+ prompt = TTY::Prompt.new
49
+ zone_name = zone['name']
49
50
 
50
- # [신규] Cloudflare Zone 목록에서 도메인을 선택하고 구성하는 메소드
51
- def configure_domain_from_zones(token)
52
- puts "\n🌐 Cloudflare 계정의 도메인 목록을 조회합니다...".colorize(:yellow)
53
-
54
- zones = get_cloudflare_zones(token)
55
-
56
- if zones.empty?
57
- puts " Cloudflare에 등록된 도메인(Zone)이 없습니다.".colorize(:red)
58
- puts "먼저 https://dash.cloudflare.com 에서 도메인을 추가해주세요.".colorize(:cyan)
59
- exit 1
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 }
60
64
  end
61
-
65
+ end
66
+
67
+ def get_server_info
62
68
  prompt = TTY::Prompt.new
63
- # 사용자가 Zone을 이름으로 선택하고, 선택 시 전체 Zone 객체를 반환하도록 설정
64
- zone_choices = zones.map { |zone| { name: "#{zone['name']} (#{zone['status']})", value: zone } }
65
-
66
- selected_zone = prompt.select("설정할 도메인(Zone)을 선택하세요:", zone_choices, filter: true, per_page: 10)
67
- zone_name = selected_zone['name']
68
- puts "✅ 선택된 Zone: #{zone_name}".colorize(:green)
69
-
70
- domain_type = prompt.select("\n어떤 종류의 도메인을 설정하시겠습니까?", [
71
- { name: "루트 도메인 (@) - 예: #{zone_name}", value: :root },
72
- { name: "서브도메인 - 예: www.#{zone_name}", value: :subdomain }
73
- ])
74
-
75
- if domain_type == :root
76
- return {
77
- type: :root,
78
- domain: zone_name,
79
- zone: zone_name,
80
- selected_zone_object: selected_zone
81
- }
82
- else # :subdomain
83
- subdomain_part = prompt.ask("사용할 서브도메인을 입력하세요 (예: www, api):") do |q|
84
- q.required true
85
- q.validate(/^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?$/, "유효한 서브도메인을 입력해주세요 (특수문자, . 사용 불가)")
86
- end
87
69
 
88
- full_domain = "#{subdomain_part.downcase}.#{zone_name}"
89
- puts "✅ 설정할 전체 도메인: #{full_domain}".colorize(:green)
70
+ puts "\n🖥️ 홈서버 연결 정보를 입력합니다.".colorize(:yellow)
90
71
 
91
- return {
92
- type: :subdomain,
93
- domain: full_domain,
94
- zone: zone_name,
95
- subdomain: subdomain_part.downcase,
96
- selected_zone_object: selected_zone
97
- }
72
+ server_address = prompt.ask("홈서버 IP 또는 도메인을 입력하세요:") do |q|
73
+ q.validate(/\A.+\z/, "서버 정보를 입력해주세요")
98
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
+ }
99
87
  end
100
88
 
101
89
  def open_token_creation_page
102
90
  puts "\n🔑 Cloudflare API 토큰이 필요합니다.".colorize(:yellow)
91
+ puts "토큰 생성 페이지를 엽니다...".colorize(:cyan)
92
+
93
+ # Cloudflare API 토큰 생성 페이지 열기
94
+ system("open 'https://dash.cloudflare.com/profile/api-tokens'")
103
95
 
104
96
  puts "\n다음 권한으로 토큰을 생성해주세요:".colorize(:yellow)
105
97
  puts ""
106
98
  puts "한국어 화면:".colorize(:gray)
107
- puts "• 영역 → DNS → 읽기".colorize(:white)
108
99
  puts "• 영역 → DNS → 편집".colorize(:white)
109
100
  puts " (영역 리소스는 '모든 영역' 선택)".colorize(:gray)
110
101
  puts ""
111
102
  puts "English:".colorize(:gray)
112
- puts "• Zone → DNS → Read".colorize(:white)
113
103
  puts "• Zone → DNS → Edit".colorize(:white)
114
104
  puts " (Zone Resources: Select 'All zones')".colorize(:gray)
115
105
  puts ""
116
-
117
- puts "토큰 생성 페이지를 엽니다...".colorize(:cyan)
118
-
119
- system("open 'https://dash.cloudflare.com/profile/api-tokens'")
120
106
  end
121
107
 
122
108
  def get_cloudflare_token
123
- existing_token = load_saved_token
124
-
125
- if existing_token
126
- puts "💾 저장된 토큰을 발견했습니다.".colorize(:cyan)
127
- if test_cloudflare_token(existing_token)
128
- puts "✅ 저장된 토큰이 유효합니다.".colorize(:green)
129
- return existing_token
130
- else
131
- puts "❌ 저장된 토큰이 만료되거나 무효합니다. 새 토큰을 입력해주세요.".colorize(:yellow)
132
- open_token_creation_page
133
- end
134
- else
135
- open_token_creation_page
136
- end
137
-
138
109
  prompt = TTY::Prompt.new
139
110
 
140
111
  token = prompt.mask("생성된 Cloudflare API 토큰을 붙여넣으세요:")
@@ -144,9 +115,9 @@ module Tayo
144
115
  exit 1
145
116
  end
146
117
 
118
+ # 토큰 유효성 간단 확인
147
119
  if test_cloudflare_token(token.strip)
148
120
  puts "✅ 토큰이 확인되었습니다.".colorize(:green)
149
- save_token(token.strip)
150
121
  return token.strip
151
122
  else
152
123
  puts "❌ 토큰이 올바르지 않거나 권한이 부족합니다.".colorize(:red)
@@ -169,42 +140,27 @@ module Tayo
169
140
  return false
170
141
  end
171
142
 
172
- def load_saved_token
173
- token_file = File.expand_path("~/.tayo")
174
- return nil unless File.exist?(token_file)
143
+ def select_cloudflare_zone(token)
144
+ puts "\n🌐 Cloudflare 도메인 목록을 조회합니다...".colorize(:yellow)
175
145
 
176
- begin
177
- content = File.read(token_file)
178
- token_line = content.lines.find { |line| line.start_with?("CLOUDFLARE_TOKEN=") }
179
- return nil unless token_line
180
-
181
- token = token_line.split("=", 2)[1]&.strip
182
- return token unless token.nil? || token.empty?
183
-
184
- nil
185
- rescue => e
186
- puts "⚠️ 토큰 파일 읽기 중 오류가 발생했습니다: #{e.message}".colorize(:yellow)
187
- nil
146
+ zones = get_cloudflare_zones(token)
147
+
148
+ if zones.empty?
149
+ puts "❌ Cloudflare에 등록된 도메인이 없습니다.".colorize(:red)
150
+ puts "먼저 https://dash.cloudflare.com 에서 도메인을 추가해주세요.".colorize(:cyan)
151
+ exit 1
188
152
  end
189
- end
190
-
191
- def save_token(token)
192
- token_file = File.expand_path("~/.tayo")
193
- timestamp = Time.now.strftime("%Y-%m-%d %H:%M:%S")
194
153
 
195
- content = <<~CONTENT
196
- # Tayo Configuration File
197
- # Created: #{timestamp}
198
- CLOUDFLARE_TOKEN=#{token}
199
- CONTENT
154
+ prompt = TTY::Prompt.new
155
+ zone_choices = zones.map { |zone| "#{zone['name']} (#{zone['status']})" }
200
156
 
201
- begin
202
- File.write(token_file, content)
203
- File.chmod(0600, token_file)
204
- puts "💾 토큰이 ~/.tayo 파일에 저장되었습니다.".colorize(:green)
205
- rescue => e
206
- puts "⚠️ 토큰 저장 중 오류가 발생했습니다: #{e.message}".colorize(:yellow)
207
- end
157
+ selected = prompt.select("도메인을 선택하세요:", zone_choices)
158
+ zone_name = selected.split(' ').first
159
+
160
+ selected_zone = zones.find { |zone| zone['name'] == zone_name }
161
+ puts "✅ 선택된 도메인: #{zone_name}".colorize(:green)
162
+
163
+ return selected_zone
208
164
  end
209
165
 
210
166
  def get_cloudflare_zones(token)
@@ -230,15 +186,53 @@ module Tayo
230
186
  exit 1
231
187
  end
232
188
 
233
- def check_existing_records(token, zone, domain_info)
189
+ def show_existing_records(token, zone)
234
190
  puts "\n🔍 기존 DNS 레코드를 확인합니다...".colorize(:yellow)
235
-
236
- target_name = (domain_info[:type] == :root) ? zone['name'] : domain_info[:domain]
237
- records = get_dns_records(token, zone['id'], target_name, ['A', 'CNAME'])
238
-
239
- puts " (확인 대상: #{target_name}, 발견된 A/CNAME 레코드: #{records.length}개)".colorize(:gray)
240
-
241
- return records
191
+
192
+ zone_id = zone['id']
193
+ zone_name = zone['name']
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
+ []
242
236
  end
243
237
 
244
238
  def get_dns_records(token, zone_id, name, types)
@@ -246,7 +240,10 @@ module Tayo
246
240
 
247
241
  types.each do |type|
248
242
  uri = URI("https://api.cloudflare.com/client/v4/zones/#{zone_id}/dns_records")
249
- uri.query = URI.encode_www_form({ type: type, name: name })
243
+ uri.query = URI.encode_www_form({
244
+ type: type,
245
+ name: name
246
+ })
250
247
 
251
248
  http = Net::HTTP.new(uri.host, uri.port)
252
249
  http.use_ssl = true
@@ -268,77 +265,42 @@ module Tayo
268
265
  puts "❌ DNS 레코드 조회 중 오류: #{e.message}".colorize(:red)
269
266
  return []
270
267
  end
271
-
272
- def setup_dns_record(token, zone, domain_info, existing_records)
268
+
269
+ def setup_dns_record(token, zone, domain_info, server_info)
273
270
  puts "\n⚙️ DNS 레코드를 설정합니다...".colorize(:yellow)
274
-
275
- prompt = TTY::Prompt.new
276
-
277
- server_info = prompt.ask("연결할 서버 IP 또는 도메인을 입력하세요:") do |q|
278
- q.validate(/\A.+\z/, "서버 정보를 입력해주세요")
279
- end
280
-
281
- ssh_user = prompt.ask("SSH 사용자 계정을 입력하세요:", default: "root")
282
-
283
- is_ip = server_info.match?(/\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\z/)
284
- record_type = is_ip ? 'A' : 'CNAME'
285
-
271
+
286
272
  zone_id = zone['id']
287
- zone_name = zone['name']
288
-
289
- final_domain = determine_final_domain(domain_info, zone_name, existing_records)
290
- all_records = get_dns_records(token, zone_id, final_domain[:name], ['A', 'CNAME'])
291
-
292
- is_already_configured = all_records.length == 1 &&
293
- all_records.first['type'] == record_type &&
294
- all_records.first['content'] == server_info
273
+ target_domain = domain_info[:domain]
274
+ server_address = server_info[:address]
275
+ record_type = server_info[:record_type]
295
276
 
296
- if is_already_configured
297
- puts "✅ DNS 레코드가 이미 올바르게 설정되어 있습니다.".colorize(:green)
298
- puts " #{final_domain[:full_domain]} → #{server_info} (#{record_type} 레코드)".colorize(:gray)
299
- else
300
- # [수정됨] 기존 레코드가 있으면 사용자에게 확인을 받습니다.
301
- if all_records.any?
302
- puts "\n⚠️ '#{final_domain[:full_domain]}'에 이미 설정된 DNS 레코드가 있습니다.".colorize(:yellow)
303
- puts "--------------------------------------------------"
304
- all_records.each do |record|
305
- puts " - 타입: ".ljust(10) + "#{record['type']}".colorize(:cyan)
306
- puts " 내용: ".ljust(10) + "#{record['content']}".colorize(:cyan)
307
- puts " 프록시: ".ljust(10) + "#{record['proxied'] ? '활성' : '비활성'}".colorize(:cyan)
308
- puts " "
309
- end
310
- puts "--------------------------------------------------"
277
+ # 대상 도메인의 기존 A/CNAME 레코드 확인
278
+ existing_records = get_dns_records(token, zone_id, target_domain, ['A', 'CNAME'])
311
279
 
312
- message = "이 레코드를 삭제하고 새로 설정하시겠습니까? (이 작업은 되돌릴 수 없습니다)"
313
- unless prompt.yes?(message)
314
- puts "❌ DNS 설정이 사용자에 의해 취소되었습니다. 스크립트를 종료합니다.".colorize(:red)
315
- exit 0
316
- end
317
-
318
- puts "\n✅ 사용자가 승인하여 기존 레코드를 삭제하고 새 레코드를 생성합니다.".colorize(:green)
319
- all_records.each do |record|
320
- delete_dns_record(token, zone_id, record['id'])
321
- end
322
- create_dns_record(token, zone_id, final_domain[:name], record_type, server_info)
280
+ if existing_records.any?
281
+ existing_record = existing_records.first
323
282
 
283
+ # 동일한 타입이고 같은 값이면 건너뛰기
284
+ if existing_record['type'] == record_type && existing_record['content'] == server_address
285
+ puts "✅ DNS 레코드가 이미 올바르게 설정되어 있습니다.".colorize(:green)
286
+ puts " #{target_domain} → #{server_address} (#{record_type} 레코드)".colorize(:gray)
324
287
  else
325
- # 기존 레코드가 없으면 바로 생성합니다.
326
- create_dns_record(token, zone_id, final_domain[:name], record_type, server_info)
288
+ # 타입이 다르거나 값이 다른 경우 삭제 후 재생성
289
+ puts "⚠️ 기존 레코드를 삭제하고 새로 생성합니다.".colorize(:yellow)
290
+ puts " 기존: #{existing_record['content']} (#{existing_record['type']}) → 새로운: #{server_address} (#{record_type})".colorize(:gray)
291
+
292
+ # 기존 레코드 삭제
293
+ delete_dns_record(token, zone_id, existing_record['id'])
294
+
295
+ # 새 레코드 생성
296
+ create_dns_record(token, zone_id, target_domain, record_type, server_address)
327
297
  end
298
+ else
299
+ # DNS 레코드 생성
300
+ create_dns_record(token, zone_id, target_domain, record_type, server_address)
328
301
  end
329
-
330
- @final_domain = final_domain[:full_domain]
331
- @server_info = server_info
332
- @ssh_user = ssh_user
333
- end
334
-
335
- def determine_final_domain(domain_info, zone_name, existing_records)
336
- case domain_info[:type]
337
- when :root
338
- { name: zone_name, full_domain: zone_name }
339
- when :subdomain
340
- { name: domain_info[:domain], full_domain: domain_info[:domain] }
341
- end
302
+
303
+ puts " #{target_domain} → #{server_address}".colorize(:cyan)
342
304
  end
343
305
 
344
306
  def create_dns_record(token, zone_id, name, type, content)
@@ -354,8 +316,7 @@ module Tayo
354
316
  type: type,
355
317
  name: name,
356
318
  content: content,
357
- ttl: 300,
358
- proxied: true
319
+ ttl: 300
359
320
  }
360
321
 
361
322
  request.body = data.to_json
@@ -363,7 +324,7 @@ module Tayo
363
324
 
364
325
  if response.code == '200'
365
326
  puts "✅ DNS 레코드가 생성되었습니다.".colorize(:green)
366
- puts " #{name} → #{content} (#{type} 레코드, 프록시됨)".colorize(:gray)
327
+ puts " #{name} → #{content} (#{type} 레코드)".colorize(:gray)
367
328
  else
368
329
  puts "❌ DNS 레코드 생성에 실패했습니다: #{response.code}".colorize(:red)
369
330
  puts response.body
@@ -385,78 +346,92 @@ module Tayo
385
346
 
386
347
  response = http.request(request)
387
348
 
388
- unless response.code == '200'
349
+ if response.code == '200'
350
+ puts "✅ 기존 DNS 레코드가 삭제되었습니다.".colorize(:green)
351
+ else
389
352
  puts "❌ DNS 레코드 삭제에 실패했습니다: #{response.code}".colorize(:red)
390
353
  puts response.body
354
+ exit 1
391
355
  end
392
356
  rescue => e
393
357
  puts "❌ DNS 레코드 삭제 중 오류: #{e.message}".colorize(:red)
358
+ exit 1
394
359
  end
395
360
 
396
- def update_deploy_config(domain_info)
361
+ def update_deploy_config(domain_info, server_info)
397
362
  puts "\n📝 배포 설정을 업데이트합니다...".colorize(:yellow)
398
-
363
+
399
364
  config_file = "config/deploy.yml"
400
-
365
+ final_domain = domain_info[:domain]
366
+ server_address = server_info[:address]
367
+ ssh_user = server_info[:ssh_user]
368
+
401
369
  unless File.exist?(config_file)
402
370
  puts "⚠️ config/deploy.yml 파일이 없습니다.".colorize(:yellow)
403
371
  return
404
372
  end
405
-
373
+
406
374
  content = File.read(config_file)
407
-
375
+
408
376
  # proxy.host 설정 업데이트
409
377
  if content.include?("proxy:")
410
- content.gsub!(/(\s+host:\s+).*$/, "\\1#{@final_domain}")
378
+ content.gsub!(/(\s+host:\s+).*$/, "\\1#{final_domain}")
411
379
  else
412
- proxy_config = "\n# Proxy configuration\nproxy:\n ssl: true\n host: #{@final_domain}\n"
380
+ # proxy 섹션이 없으면 추가
381
+ proxy_config = "\n# Proxy configuration\nproxy:\n ssl: true\n host: #{final_domain}\n"
413
382
  content += proxy_config
414
383
  end
415
-
384
+
416
385
  # servers 설정 업데이트
417
386
  if content.match?(/servers:\s*\n\s*web:\s*\n\s*-\s*/)
418
- content.gsub!(/(\s*servers:\s*\n\s*web:\s*\n\s*-\s*)[\w.-]+/, "\\1#{@server_info}")
387
+ content.gsub!(/(\s*servers:\s*\n\s*web:\s*\n\s*-\s*)[\d.]+/, "\\1#{server_address}")
419
388
  end
420
-
389
+
421
390
  # ssh user 설정 업데이트
422
- if @ssh_user && @ssh_user != "root"
391
+ if ssh_user && ssh_user != "root"
423
392
  if content.match?(/^ssh:/)
424
- content.gsub!(/^ssh:\s*\n\s*user:\s*\w+/, "ssh:\n user: #{@ssh_user}")
393
+ # 기존 ssh 섹션 업데이트
394
+ content.gsub!(/^ssh:\s*\n\s*user:\s*\w+/, "ssh:\n user: #{ssh_user}")
425
395
  else
396
+ # ssh 섹션 추가 (accessories 섹션 앞에 추가)
426
397
  if content.match?(/^# Use accessory services/)
427
- 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")
428
399
  else
429
- content += "\n# Use a different ssh user than root\nssh:\n user: #{@ssh_user}\n"
400
+ # 파일 끝에 추가
401
+ content += "\n# Use a different ssh user than root\nssh:\n user: #{ssh_user}\n"
430
402
  end
431
403
  end
432
404
  end
433
-
405
+
434
406
  File.write(config_file, content)
435
407
  puts "✅ config/deploy.yml이 업데이트되었습니다.".colorize(:green)
436
- puts " proxy.host: #{@final_domain}".colorize(:gray)
437
- puts " servers.web: #{@server_info}".colorize(:gray)
438
- if @ssh_user && @ssh_user != "root"
439
- puts " ssh.user: #{@ssh_user}".colorize(:gray)
440
- end
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"
441
411
  end
442
412
 
443
413
  def commit_cloudflare_changes(domain_info)
444
414
  puts "\n📝 변경사항을 Git에 커밋합니다...".colorize(:yellow)
445
415
 
446
- status_output = `git status --porcelain config/deploy.yml`.strip
416
+ # 변경된 파일이 있는지 확인
417
+ status_output = `git status --porcelain`.strip
447
418
 
448
419
  if status_output.empty?
449
- puts "ℹ️ 커밋할 변경사항이 없습니다.".colorize(:cyan)
420
+ puts "ℹ️ 커밋할 변경사항이 없습니다.".colorize(:yellow)
450
421
  return
451
422
  end
452
423
 
453
- system("git add config/deploy.yml")
424
+ # Git add
425
+ system("git add -A")
454
426
 
455
- commit_message = "feat: Configure Cloudflare DNS for #{@final_domain}\n\n- Set DNS record for #{@final_domain} to point to #{@server_info}\n- Update deployment configuration in config/deploy.yml\n\n🤖 Generated by Tayo"
427
+ # Commit 메시지 생성
428
+ commit_message = "Configure Cloudflare DNS settings\n\n- Setup DNS for domain: #{domain_info[:domain]}\n- Configure server IP: #{domain_info[:server_ip]}\n- Update deployment configuration\n- Add proxy host settings\n\n🤖 Generated with Tayo"
456
429
 
430
+ # Commit 실행
457
431
  if system("git commit -m \"#{commit_message}\"")
458
432
  puts "✅ 변경사항이 성공적으로 커밋되었습니다.".colorize(:green)
459
433
 
434
+ # GitHub에 푸시
460
435
  if system("git push", out: File::NULL, err: File::NULL)
461
436
  puts "✅ 변경사항이 GitHub에 푸시되었습니다.".colorize(:green)
462
437
  else
@@ -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)