2016-03-05 77 views
1

我需要建議來優化我的木偶代碼。作爲輸入,我有兩種類型的數據 - 包含端口號的數組和包含虛擬主機細節的哈希,並且我喜歡將它們中的每一個與另一個(每個端口的每個虛擬主機)混合。每個虛擬主機和端口的結果都應該是apache :: vhost。假設這些類:通過2組數據循環通過木偶 - 優化

class proxy(
    $ports = ['80', '8080'], 
) { 
    class { 'apache': 
    default_vhost => false, 
    } 

$vhosts = { 
'myhost1' => { 
    serveraliases => ['page.myhost1', ], 
    proxy_pass => [ 
    { 
     'path' => '/url/', 
     'url' => 'http://localhost:8088/anotherurl/' 
    }, 
    ], 
}, 
'myhost2' => { 
    serveraliases => ['page.myhost2', ], 
    proxy_pass => [ 
    { 
     'path' => '/url/', 
     'url' => 'http://localhost:8088/anotherurl/' 
    }, 
    ], 
}, 
proxy::vhosts { $ports: 
    vhosts => $vhosts, 
} 
} 

現在我需要做的一點點魔法使虛擬主機定義的uniq(我追加端口號的虛擬主機的形式myhost1_80名):

define proxy::vhosts (
    $vhosts, 
) { 

    $vhosts_keys = keys($vhosts) 

    $servername_port_string = join($vhosts_keys, "_${title},") 
    $servername_port_string_full = "${servername_port_string}_${title}" 

    $servername_port_array = split($servername_port_string_full, ',') 

    proxy::vhost { $servername_port_array: 
    vhosts => $vhosts, 
    port => $name, 
    } 

} 

最後創建阿帕奇::虛擬主機用於分離後的各虛擬主機和端口定義名稱先前合併(所以host1_80分成host1和80):

define proxy::vhost (
    $vhosts, 
    $port, 
) { 

    $servername_and_port = split($name, '_') 

    apache::vhost { $name: 
    servername => $servername_and_port[0], 
    serveraliases => $vhosts[$servername_and_port[0]]['serveraliases'], 
    docroot  => '/var/www', 
    port   => $servername_and_port[1], 
    directories => [ 
     { 'path'  => '/var/www', 
     'provider' => 'files', 
     'deny'  => 'from all' 
     }, 
    ], 
    proxy_pass => $vhosts[$servername_and_port[0]]['proxy_pass'], 
    } 

} 

不幸阿帕奇類不支持陣列作爲輸入端口價值,我不能使用更新版本的puppet> 3.2(據我記得 - 與每個和其他新功能介紹)。這些可以以更簡單的方式完成嗎?

+0

典型的XY問題答案。你爲什麼想這樣做? – Robo

+0

那麼我可以爲每個虛擬主機和每個端口添加哈希條目,但這意味着我需要在哈希中創建(虛擬主機數量*端口數量)條目,因爲我一次只能提供一個端口到apache :: vhost,想自動化這一點。 – Filip

回答

0

對於木偶3,你可以使用create_resources,一些紅寶石組合:

define b(
    $port, 
    $vhost) 
{ 
    notice("created ${vhost}:${port}") 
} 

class a(
    $all_ports, 
    $all_vhosts, 
) { 
    $y = inline_template("<%= require 'yaml'; \ 
         t = @all_ports.product(@all_vhosts).map { |(port, vhost)| \ 
          [\"#{port}:#{vhost}\", { port: port, vhost: vhost }] \ 
         }; \ 
         YAML.dump(Hash[t]) %>") 
    $spec = parseyaml($y) 
    create_resources('b', $spec) 
} 

class { 'a': 
    all_ports => [8080, 80], 
    all_vhosts => ['one.example.com', 'two.example.com'], 
} 

parseyaml是STDLIB。如果你創建了一個puppet函數而不是inline_template,那會更漂亮。

+0

謝謝,看起來比我的分辨率更清潔,本週肯定會檢查解決方案。 – Filip