2016-03-05 61 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