Skip to content

Commit 6e94347

Browse files
committed
refactor: IPアドレス検証ロジックをSakuraServerUserAgentクラスに統一
- DRY原則に従い、重複していたIP検証ロジックを共通化 - valid_ip_address?メソッド: Rubyらしく?付きで真偽値を返す - normalize_ip_addressメソッド: IP正規化を別途提供 - 不要なラッパーメソッドとVALID_IP_PATTERN定数を削除
1 parent 09bc5a4 commit 6e94347

File tree

3 files changed

+84
-70
lines changed

3 files changed

+84
-70
lines changed

Rakefile

Lines changed: 52 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
require "rspec/core/rake_task"
2-
require 'ipaddr'
32
require 'fileutils'
43
require 'json'
54
require 'time'
@@ -94,27 +93,16 @@ namespace :server do
9493
"または: IP_ADDRESS=192.168.1.1 rake server:find_by_ip"
9594
end
9695

97-
# セキュリティのためRubyのIPAddrを使用してIPアドレスを検証
98-
begin
99-
validated_ip = IPAddr.new(ip)
100-
101-
# プライベート/特殊IPをチェック
102-
if validated_ip.private? || validated_ip.loopback? || validated_ip.link_local?
103-
abort "❌ エラー: プライベートまたは特殊IPアドレスは許可されていません: #{ip}"
104-
end
105-
106-
# さくらクラウドのIP範囲の追加検証(オプション)
107-
if ENV['VALIDATE_SAKURA_RANGE'] == 'true'
108-
unless in_sakura_cloud_range?(validated_ip)
109-
abort "❌ エラー: IPアドレスがさくらクラウドの範囲外です: #{ip}"
110-
end
111-
end
112-
113-
validated_ip_str = validated_ip.to_s
114-
rescue IPAddr::InvalidAddressError => e
115-
abort "❌ エラー: 無効なIPアドレス形式: #{ip}\n#{e.message}"
96+
# IPアドレスの検証(SakuraServerUserAgentの共通メソッドを使用)
97+
require_relative 'scripts/sakura_server_user_agent'
98+
99+
unless SakuraServerUserAgent.valid_ip_address?(ip)
100+
abort "❌ エラー: 無効なIPアドレス形式: #{ip}"
116101
end
117102

103+
# IPアドレスを正規化
104+
validated_ip_str = SakuraServerUserAgent.normalize_ip_address(ip)
105+
118106
puts "✅ 有効なIPアドレス: #{validated_ip_str}"
119107
puts "🔍 サーバー情報を検索中..."
120108
puts "-" * 50
@@ -359,51 +347,53 @@ namespace :server do
359347
end
360348
end
361349

362-
# ヘルパーメソッド(将来のフェーズで拡張予定)
363-
def in_sakura_cloud_range?(ip_addr)
364-
# さくらクラウドのIP範囲(現時点では簡略化)
365-
sakura_ranges = [
366-
IPAddr.new("153.127.0.0/16"), # 石狩第二ゾーン
367-
IPAddr.new("163.43.0.0/16"), # 東京ゾーン
368-
IPAddr.new("133.242.0.0/16"), # 大阪ゾーン
369-
]
370-
371-
sakura_ranges.any? { |range| range.include?(ip_addr) }
372-
end
350+
# ヘルパーメソッド(将来の拡張用に保持)
351+
# 注: 現在は使用されていません(YAGNI原則により簡素化)
352+
# def in_sakura_cloud_range?(ip_addr)
353+
# sakura_ranges = [
354+
# IPAddr.new("153.127.0.0/16"), # 石狩第二ゾーン
355+
# IPAddr.new("163.43.0.0/16"), # 東京ゾーン
356+
# IPAddr.new("133.242.0.0/16"), # 大阪ゾーン
357+
# ]
358+
# sakura_ranges.any? { |range| range.include?(ip_addr) }
359+
# end
373360

374361
# ================================================================
375-
# 並列実行タスク(Rakeの高度な機能
362+
# 並列実行タスク(将来の実装用にコメントアウト
376363
# ================================================================
377-
namespace :parallel do
378-
desc "複数サーバーの状態を並列チェック"
379-
multitask :check_all => ['server:validate_env'] do
380-
# servers.csvから全サーバーをチェック
381-
servers = CSV.read('servers.csv', headers: true)
382-
383-
# 並列でステータスチェックを実行
384-
threads = servers.map do |server|
385-
Thread.new do
386-
begin
387-
result = `ruby scripts/initialize_server.rb --find #{server['Name']} 2>&1`
388-
{ name: server['Name'], status: $?.success? ? 'OK' : 'ERROR', details: result }
389-
rescue => e
390-
{ name: server['Name'], status: 'ERROR', details: e.message }
391-
end
392-
end
393-
end
394-
395-
results = threads.map(&:value)
396-
397-
# 結果をサマリー表示
398-
puts "\n" + "=" * 50
399-
puts "サーバーステータスサマリー"
400-
puts "=" * 50
401-
results.each do |r|
402-
status_icon = r[:status] == 'OK' ? '✅' : '❌'
403-
puts "#{status_icon} #{r[:name]}: #{r[:status]}"
404-
end
405-
end
406-
end
364+
# YAGNI原則により、実際に必要になるまでコメントアウト
365+
# 注意: 200サーバーの並列チェックはAPI制限のリスクあり
366+
#
367+
# namespace :parallel do
368+
# desc "複数サーバーの状態を並列チェック"
369+
# multitask :check_all => ['server:validate_env'] do
370+
# # servers.csvから全サーバーをチェック
371+
# servers = CSV.read('servers.csv', headers: true)
372+
#
373+
# # 並列でステータスチェックを実行
374+
# threads = servers.map do |server|
375+
# Thread.new do
376+
# begin
377+
# result = `ruby scripts/initialize_server.rb --find #{server['Name']} 2>&1`
378+
# { name: server['Name'], status: $?.success? ? 'OK' : 'ERROR', details: result }
379+
# rescue => e
380+
# { name: server['Name'], status: 'ERROR', details: e.message }
381+
# end
382+
# end
383+
# end
384+
#
385+
# results = threads.map(&:value)
386+
#
387+
# # 結果をサマリー表示
388+
# puts "\n" + "=" * 50
389+
# puts "サーバーステータスサマリー"
390+
# puts "=" * 50
391+
# results.each do |r|
392+
# status_icon = r[:status] == 'OK' ? '✅' : '❌'
393+
# puts "#{status_icon} #{r[:name]}: #{r[:status]}"
394+
# end
395+
# end
396+
# end
407397

408398
# ================================================================
409399
# クリーンタスク(Rake標準機能の活用)

scripts/initialize_server.rb

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ class ServerInitializer
2828
IP_PATTERN = /(?:IPアドレス|IP)[::]\s*【?(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})】?/
2929

3030
# IPアドレスの厳密な検証パターン
31-
VALID_IP_PATTERN = /\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z/
31+
# 注: RakefileでIPAddrクラスによる検証を行うため、ここでの重複検証は不要(YAGNI)
32+
# VALID_IP_PATTERN = /\A(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\z/
3233

3334

3435
# テスト用サーバー名の安全管理(誤削除防止)
@@ -121,7 +122,7 @@ def show_help
121122
# 安全性チェック: テスト用サーバー以外の削除には追加確認
122123
def confirm_safe_deletion(target)
123124
# IPアドレスの場合はサーバー名を取得
124-
if valid_ip_address?(target)
125+
if SakuraServerUserAgent.valid_ip_address?(target)
125126
server_info = find_server_by_ip(target)
126127
server_name = server_info ? server_info['Name'] : nil
127128
else
@@ -161,7 +162,7 @@ def run_delete_mode
161162
puts ""
162163

163164
# IPアドレスの検証
164-
unless valid_ip_address?(@input)
165+
unless SakuraServerUserAgent.valid_ip_address?(@input)
165166
puts "❌ エラー: 無効なIPアドレス形式です: #{@input}"
166167
puts ""
167168
puts "正しいIPアドレス形式で指定してください(例: 192.168.1.1)"
@@ -366,11 +367,6 @@ def find_by_name
366367
display_deletion_plan(server_info, ip_address, dojo_name)
367368
end
368369

369-
# IPアドレスの検証
370-
def valid_ip_address?(ip)
371-
return false if ip.nil? || ip.empty?
372-
!!(ip =~ VALID_IP_PATTERN)
373-
end
374370

375371
# サーバー情報の詳細表示(削除用)
376372
def display_server_details_for_deletion(server)

scripts/sakura_server_user_agent.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
#!/usr/bin/env ruby
22
require_relative 'smart_wait_helper'
3+
require 'ipaddr' # IP検証用
34

45
class SakuraServerUserAgent
56
include SmartWaitHelper
@@ -26,6 +27,33 @@ class SakuraServerUserAgent
2627
# gh-pagesブランチで公開される実際のサーバー情報
2728
INSTANCES_CSV_URL = "https://raw.githubusercontent.com/coderdojo-japan/dojopaas/refs/heads/gh-pages/instances.csv"
2829

30+
# IPアドレス検証用のクラスメソッド(共通化)
31+
# @param ip [String] 検証するIPアドレス
32+
# @return [Boolean] 有効なIPアドレスの場合true、無効な場合false
33+
def self.valid_ip_address?(ip)
34+
return false if ip.nil? || ip.empty?
35+
36+
begin
37+
IPAddr.new(ip)
38+
true
39+
rescue IPAddr::InvalidAddressError
40+
false
41+
end
42+
end
43+
44+
# IPアドレスを正規化して返す
45+
# @param ip [String] 正規化するIPアドレス
46+
# @return [String, nil] 正規化されたIPアドレス、無効な場合はnil
47+
def self.normalize_ip_address(ip)
48+
return nil if ip.nil? || ip.empty?
49+
50+
begin
51+
IPAddr.new(ip).to_s
52+
rescue IPAddr::InvalidAddressError
53+
nil
54+
end
55+
end
56+
2957
# jsのserver.createで使っているフィールドを参考
3058
def initialize(zone:0, packet_filter_id:nil, name:nil, description:nil, zone_id:"is1b",
3159
tags:nil, pubkey:nil, resolve:nil, verbose:false)

0 commit comments

Comments
 (0)