-
Notifications
You must be signed in to change notification settings - Fork 56
Network type and provider #47
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
21d45e3
fc6717e
f4e6db1
c524101
c02fcd8
c1ca70b
9c9e007
274d741
2776552
88380ad
4d39871
adf7a13
4a41b6d
cc815b5
108b2a1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
require 'libvirt' | ||
require 'erb' | ||
require 'nokogiri' | ||
|
||
Puppet::Type.type(:network).provide(:libvirt) do | ||
desc "Create domains with libvirt" | ||
|
||
mk_resource_methods | ||
|
||
$conn = Libvirt::open('qemu:///system') | ||
|
||
def self.parse_network(network) | ||
doc = Nokogiri::XML(network.xml_desc) | ||
definition = {} | ||
definition[:name] = doc.at_xpath('//name').content | ||
definition[:uuid] = doc.at_xpath('//uuid').content | ||
if doc.at_xpath('//bridge') and doc.at_xpath('//bridge').attribute('name') | ||
definition[:bridge] = doc.at_xpath('//bridge').attribute('name').content | ||
end | ||
if doc.at_xpath('//forward') | ||
forward = doc.at_xpath('//forward') | ||
if forward.attribute('mode') | ||
definition[:forward_mode] = forward.attribute('mode').content | ||
end | ||
if forward.attribute('dev') | ||
definition[:forward_dev] = forward.attribute('dev').content | ||
end | ||
if forward.xpath('//interface') | ||
definition[:forward_interfaces] = [] | ||
for int in forward.xpath('//interface') | ||
definition[:forward_interfaces].push(int.attribute('dev').content) | ||
end | ||
end | ||
end | ||
if doc.xpath('//ip') | ||
definition[:ip] = [] | ||
definition[:ipv6] = [] | ||
for ip in doc.xpath('//ip') | ||
data = {} | ||
for setting in ['address', 'netmask', 'prefix'] | ||
if ip.attribute(setting) | ||
data[setting] = ip.attribute(setting).content | ||
end | ||
end | ||
if ip.at_xpath('//dhcp') | ||
data[:dhcp] = {} | ||
for setting in ['start', 'end'] | ||
data[:dhcp][setting] = ip.at_xpath('//dhcp/range').attribute(setting).content | ||
end | ||
if ip.at_xpath('//dhcp/bootp') | ||
data[:dhcp][:bootp_file] = ip.at_xpath('//dhcp/bootp').attribute('file').content | ||
end | ||
end | ||
if ip.attribute('family') and ip.attribute('family').content == 'ipv6' | ||
definition[:ipv6].push(data) | ||
else | ||
definition[:ip].push(data) | ||
end | ||
end | ||
end | ||
if doc.at_xpath('//mac') | ||
definition[:mac] = doc.at_xpath('//mac').attribute('address').content | ||
end | ||
return definition | ||
end | ||
|
||
def self.instances | ||
networks = [] | ||
for net in $conn.list_all_networks() do | ||
hash = parse_network(net) | ||
hash[:autostart] = net.autostart? | ||
networks << new(hash) | ||
end | ||
return networks | ||
end | ||
|
||
def self.prefetch(resources) | ||
instances.each do |prov| | ||
if resource = resources[prov.name] | ||
resource.provider = prov | ||
end | ||
end | ||
end | ||
|
||
def create | ||
# @property_hash = @resource | ||
end | ||
|
||
|
||
def flush | ||
debug("flushing '" + @resource[:name] + "' with: " + @property_hash.to_s ) | ||
net_xml = <<EOF | ||
<network> | ||
<name><%= @resource[:name] %></name> | ||
<% if @property_hash[:uuid] %><uuid><%= @property_hash[:uuid] %></uuid><% end %> | ||
<% if @property_hash[:mac] %> | ||
<mac address='<%= @property_hash[:mac] %>'/> | ||
<% end %> | ||
<% if @resource[:forward_mode] %> | ||
<forward<% if @resource[:forward_dev] %> dev='<%= @resource[:forward_dev] %>'<%end%> mode='<%= @resource[:forward_mode] %>'<% if !@resource[:forward_interfaces] %>/<%end%>> | ||
<% if @resource[:forward_interfaces] %> | ||
<% @resource[:forward_interfaces].each do |dev| %> | ||
<interface dev='<%= dev %>'/> | ||
<% end %> | ||
</forward> | ||
<% end %> | ||
<% end %> | ||
<% if @resource[:bridge] %> | ||
<bridge name='<%= @resource[:bridge] %>'<% if @resource[:forward_mode] and @resource[:forward_mode] != 'bridge' %> stp='on' delay='0'<%end%>/> | ||
<% end %> | ||
<%if @resource[:ip] %> | ||
<% @resource[:ip].each do |ip| %> | ||
<ip<%if ip['address']%> address='<%=ip['address']%>'<%end%><% if ip['netmask']%> netmask='<%=ip['netmask']%>'<%end%><% if ip['prefix']%> prefix='<%=ip['prefix']%>'<%end%><% unless ip['dhcp'] %>/<% end %>> | ||
<% if ip['dhcp'] %> | ||
<% dhcp = ip['dhcp'] %> | ||
<dhcp> | ||
<% if dhcp['start'] and dhcp['end']%> | ||
<range start='<%=dhcp['start']%>' end='<%=dhcp['end']%>'/> | ||
<%end%> | ||
<% if dhcp['bootp_file']%> | ||
<bootp file='<%= dhcp['bootp_file'] %>'<% if dhcp['bootp_server']%> server='<%=dhcp['bootp_server']%>'<%end%>/> | ||
<%end%> | ||
</dhcp> | ||
</ip> | ||
<% end%> | ||
<% end%> | ||
<%end%> | ||
<% if @resource[:ipv6] %> | ||
<% @resource[:ipv6].each do |ip| %> | ||
<ip family='ipv6'<% if ip['address']%> address='<%=ip['address']%>'<%end%><% if ip['netmask']%> netmask='<%=ip['netmask']%>'<%end%><% if ip['prefix']%> prefix='<%=ip['prefix']%>'<%end%><% unless ip['dhcp'] %>/<% end %>> | ||
<% if ip['dhcp'] %> | ||
<% dhcp = ip['dhcp'] %> | ||
<dhcp> | ||
<% if dhcp['start'] and dhcp['end']%> | ||
<range start='<%=dhcp['start']%>' end='<%=dhcp['end']%>'/> | ||
<%end%> | ||
</dhcp> | ||
</ip> | ||
<% end%> | ||
<% end%> | ||
<%end%> | ||
</network> | ||
EOF | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. heh. this is not pretty. actually, from what i gather, it's the same as my old template, but the whole bits around it ensure that it'll be a lot more stable. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This bit started as a simple copy of the existing template, then got tweaked as needed. |
||
new_net_xml = ERB.new(net_xml).result(binding) | ||
debug("generated: " + new_net_xml ) | ||
begin | ||
net = $conn.define_network_xml(new_net_xml) | ||
rescue Libvirt::Error => e | ||
puts "error", e | ||
end | ||
end | ||
|
||
def exists? | ||
begin | ||
net = $conn.lookup_network_by_name(name) | ||
true | ||
rescue Libvirt::RetrieveError => e | ||
false | ||
end | ||
end | ||
|
||
def destroy | ||
net = $conn.lookup_network_by_name(name) | ||
net.destroy | ||
net.undefine | ||
end | ||
|
||
def autostart | ||
@property_hash[:autostart] == true | ||
end | ||
|
||
def autostart=(value) | ||
net = $conn.lookup_network_by_name(name) | ||
net.autostart = value | ||
end | ||
|
||
end |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
Puppet::Type.newtype(:network) do | ||
@doc = "manages domains with libvirt" | ||
|
||
ensurable | ||
|
||
newparam(:name) do | ||
desc "The name of the domain." | ||
end | ||
|
||
newproperty(:autostart) do | ||
desc "Whether to start this network at boot time" | ||
end | ||
|
||
newproperty(:bridge) do | ||
desc "Name of the bridge this network will be attached to" | ||
end | ||
|
||
newproperty(:forward_mode) do | ||
desc "One of nat, route, bridge, vepa, passthrough, private, hostdev" | ||
#TODO nat must have an ip address | ||
#TODO A network with forward mode='bridge' can specify a bridge name or a forward dev, but not both | ||
end | ||
|
||
newproperty(:forward_dev) do | ||
desc "The interface to forward, useful in bridge and route mode" | ||
end | ||
|
||
newproperty(:forward_interfaces, :array_matching => :all) do | ||
desc "An array of interfaces to forwad" | ||
end | ||
|
||
newproperty(:ip, :array_matching => :all ) do | ||
desc "a hash with | ||
address | ||
netmask (or alterntively prefix) | ||
dhcp This is another hash that consists of | ||
start - start of the range | ||
end - end of the range | ||
host - an array of hosts" | ||
end | ||
|
||
newproperty(:ipv6, :array_matching => :all) do | ||
desc "a hash with | ||
address | ||
netmask (or alterntively prefix) | ||
dhcp This is another hash that consists of | ||
start - start of the range | ||
end - end of the range | ||
host - an array of hosts | ||
Note: The following options are not supported on IPv6 networks | ||
bootp_file - A file to serve for servers booting from PXE | ||
bootp_server - Which server that file is served from" | ||
end | ||
|
||
newproperty(:mac) do | ||
desc "mac address for the bridge" | ||
end | ||
|
||
end |
This file was deleted.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is there a reason why this code is commented out?
can we do better here? Or should we just remove
#create
altogether, seeing as this is done in#flush
?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The commented out line is leftover from some experimentation, I'll remove it. The
create
function must exist, even if it's empty, otherwise puppet will throw an error.