Commit 11882538 authored by Your Name's avatar Your Name
Browse files

start changing hiera structure / some tests

parent d3cf1c9f
*.swp
*.swo
require puppetlabs_spec_helper/rake_tasks
module Puppet::Parser::Functions
newfunction(:gen_consistent_uuid, :type => :rvalue) do |args|
# compute sha1 hash of all keys concatenated
sha1 = Digest::SHA1.hexdigest(args.join(''))
# generate a QEMU/KVM UUID
"#{sha1[0..7]}-#{sha1[8..11]}-#{sha1[12..15]}-#{sha1[16..19]}-#{sha1[20..31]}"
end
end
......@@ -3,37 +3,30 @@ module Puppet::Parser::Functions
Puppet::Parser::Functions.function('generate_mac')
name = args[0]
int_ip = args[1]
int_mac = args[2]
ext_ip = args[3]
ext_mac = args[4]
ext_net = args[5]
int_method = args[6]
ext_method = args[7]
type = args[8]
interfaces = Array.new
#FIXME: put the 0.0.0.0 check back
if not int_method=='none' then
if not int_mac.empty? then
interfaces << {'filter' => name + "-internal", 'network' => 'net-internal', 'mac' => int_mac, 'type' => type, 'ip' => int_ip, 'name' => name + "-internal"}
in_if = args[0]
out_if = Array.new
type = 'virtio'
in_if.each do |intf|
out = {}
if not intf['ip'] then
# calculate ip from host
out['ip'] = '1.2.3.4'
else
interfaces << {'filter' => name + "-internal", 'network' => 'net-internal', 'mac' => function_libvirt_generate_mac([int_ip]), 'type' => type, 'ip' => int_ip, 'name' => name + "-internal"}
out['ip'] = intf['ip']
end
end
if not ext_method=='none' then
if not ext_mac.empty? then
interfaces << {'filter' => name + "-external", 'network' => ext_net, 'mac' => ext_mac, 'type' => type, 'ip' => ext_ip, 'name' => name + "-external"}
if not intf['mac'] then
# gen mac
out['mac'] = function_libvirt_generate_mac([out['ip']])
else
interfaces << {'filter' => name + "-external", 'network' => ext_net, 'mac' => function_libvirt_generate_mac([ext_ip]), 'type' => type, 'ip' => ext_ip, 'name' => name + "-external"}
out['mac'] = intf['mac']
end
out['type'] = type
out['network'] = intf['network']
out_if.append(out)
end
interfaces
out_if
end
end
#
module Puppet::Parser::Functions
newfunction(:libvirt_generate_mac, type: :rvalue, doc: <<-'ENDHEREDOC') do |args|
compute sha1 hash of all keys concatenated, only the first 6
hex digits will be used
@return a mac address
ENDHEREDOC
sha1 = Digest::SHA1.hexdigest(args.join(''))
# generate address in the QEMU/KVM MAC OID
'52:54:00:' + "#{sha1[0..1]}:#{sha1[2..3]}:#{sha1[4..5]}"
end
end
#
class hypervisor (
String $type = 'kvm',
String $nat_netmask,
String $nat_dhcp_start,
String $nat_dhcp_end,
) {
# Make sure we have libvirt installed and running
class {'libvirt': }
# Install packages to make sysadmin life easy on hypervisors
$packages = [
'bridge-utils',
'build-essential',
'debootstrap',
'devscripts',
'fakeroot',
'ipmitool',
'linux-source',
'lm-sensors',
'smartmontools',
]
ensure_packages($packages)
}
define hypervisor::network (
$ensure = 'present' ,
# allocation network is to make host addresses readable (when your network uses a netmask that are not /24 )
Stdlib::IP::Address $allocation_network,
Stdlib::IP::Address $netmask,
Stdlib::IP::Address $network,
Stdlib::IP::Address $gateway,
$dns = undef,
Hash $routes = {},
String $bridge = $name,
String $forward_mode = 'bridge',
# FIXME: config should not be separate for nat
Stdlib::IP::Address $nat_ip = '10.13.12.1',
Stdlib::IP::Address $nat_netmask = '255.255.255.0',
Stdlib::IP::Address $nat_dhcp_start = '10.13.12.42',
Stdlib::IP::Address $nat_dhcp_end = '10.13.12.254',
$nat_forward_dev = lookup(profile::primary_network::interface),
) {
alert($name)
libvirt::network { $name:
forward_mode => 'bridge',
bridge => $name,
}
if $forward_mode == 'nat' {
libvirt::network { $name:
forward_mode => $forward_mode,
forward_dev => lookup(profile::primary_network::interface),
bridge => 'br-nat',
ip_address => $nat_ip,
ip_netmask => $nat_netmask,
dhcp_start => $nat_dhcp_start,
dhcp_end => $nat_dhcp_end,
}
} else {
libvirt::network { $name:
forward_mode => 'bridge',
bridge => $bridge,
}
if defined(Network::Interface["$bridge"]) {
#if defined(Mroute[$bridge]) {
# Error: Evaluation Error: Error while evaluating a Resource Statement, Evaluation Error: A substring operation does not accept a String as a character index. Expected an Integer (file: /etc/puppet/code/modules/hypervisor/manifests/network.pp, line: 44, column: 31) (file: /etc/puppet/code/modules/hypervisor/manifests/networks.pp, line: 37) on node hypr.example.com
#if true {
#FIXME: how the fuck is this supposed to work??
# configures hypervisor as the gateway for now
network::interface { $name:
bridge_ports => ['none'],
bridge_stp => 'off',
bridge_fd => 0,
address => $gateway,
netmask => $netmask,
alert("Multiple networks on same bridge, make sure that gateway is the same on both of them (p2p routes), and netmask is /32")
# FIXME: ^ make sure that is the case
} else {
# FIXME: configures hypervisor as the gateway for now
network::interface { $bridge:
bridge_ports => ['none'],
bridge_stp => 'off',
bridge_fd => 0,
address => $gateway,
netmask => $netmask,
}
network::mroute { $bridge:
routes => $routes,
}
}
}
}
......@@ -9,6 +9,10 @@ class hypervisor::networks (
require put::base
if "${operatingsystem}" == "Debian" {
require put::buster
......@@ -29,8 +33,8 @@ class hypervisor::networks (
# create networks's defined in hiera
$networks = hiera_hash('networks')
create_resources ( hypervisor::network , $networks )
$networks = hiera_hash('networks')
create_resources ( hypervisor::network , $networks )
}
}
......
......@@ -4,10 +4,10 @@
define hypervisor::vm::deploy (
$ensure = 'present',
String $domain = lookup('domain', undef, undef, 'nodomainset.la'),
String $domain = lookup('domain'),
Stdlib::Fqdn $public_hostname = "${name}.${domain}",
String $devices_profile = '9p',
String $dom_profile = '9p',
String $devices_profile = 'headless',
String $dom_profile = 'headless',
String $rootsize = '4G',
String $swapsize = '1G',
Boolean $datadisk = false,
......@@ -18,29 +18,11 @@ define hypervisor::vm::deploy (
# String $initrd = $hypervisor::vm::initrd,
# Integer $memory = 1000,
# Integer $cpus = 1,
String $debian_version = 'buster',
String $internal_method = 'static',
Optional[ Stdlib::IP::Address::V4::Nosubnet ] $internal_ip = '0.0.0.0',
Optional[ Stdlib::IP::Address::V4 ] $internal_gw = '0.0.0.0',
Optional[ Stdlib::IP::Address::V4 ] $internal_nm = '255.255.255.0',
String $external_method = 'static',
Optional[ Stdlib::IP::Address::V4::Nosubnet ] $external_ip = '0.0.0.0',
Optional[ Stdlib::IP::Address::V4 ] $external_gw = '0.0.0.0',
Optional[ Stdlib::IP::Address::V4 ] $external_nm = '255.255.255.0',
Optional[ Stdlib::MAC ] $internal_mac = undef,
Optional[ Stdlib::MAC ] $external_mac = undef,
# those are not optional, if they are missing, vm doesn't start
String $internal_net ,
String $external_net ,
String $os_version = 'buster',
Optional[ Stdlib::IP::Address::V4 ] $dns = '0.0.0.0',
Array $internal_tcp_services = [22],
Array $internal_udp_services = [],
Array $internal_custom_tcp_rules = [], # syntax: [{remote_ip => port}, ... ]
Array $internal_custom_udp_rules = [], # syntax: [{remote_ip => port}, ... ]
Array $external_tcp_services = [],
Array $external_udp_services = [],
Array $external_custom_tcp_rules = [], # syntax: [{remote_ip => port}, ... ]
Array $external_custom_udp_rules = [], # syntax: [{remote_ip => port}, ... ]
Array $net_interfaces = [],
$type = 'lala',
) {
Exec {
......@@ -142,7 +124,7 @@ define hypervisor::vm::deploy (
#FIXME: mkrootdisk does not get run again when it fails
# to have puppet rerun this script, make a new filesystem on the disk (deleting files does not work)
Exec { "/usr/local/bin/mkrootdisk.sh ${block_prefix}/${hypervisor::vm::root_vg}/${name}-disk":
# onlyif => "test `/usr/local/bin/inodecount.sh ${block_prefix}/${hypervisor::vm::root_vg}/${name}-disk` = 11",
onlyif => "test `/usr/local/bin/inodecount.sh ${block_prefix}/${hypervisor::vm::root_vg}/${name}-disk` = 11",
environment => ["INTIP=${internal_ip}",
"INTGW=${internal_gw}",
"INTNM=${internal_nm}",
......@@ -155,7 +137,7 @@ define hypervisor::vm::deploy (
"DOMAIN=${hypervisor::vm::domain}",
"INTMETHOD=${internal_method}",
"EXTMETHOD=${external_method}",
"DEBIAN_VERSION=${debian_version}",
"DEBIAN_VERSION=${os_version}",
],
logoutput => true,
......@@ -242,6 +224,8 @@ define hypervisor::vm::deploy (
}
}
}
$disks = undef
} else {
......@@ -255,6 +239,9 @@ define hypervisor::vm::deploy (
$disks = hypervisor_disks($name,$hypervisor::vm::root_vg,$hypervisor::vm::swap_vg,$hypervisor::vm::data_vg,$datadisk)
}
libvirt::domain { $name:
type => $hypervisor::vm::type,
devices_profile => $devices_profile,
......@@ -262,7 +249,7 @@ libvirt::domain { $name:
devices => $devices,
disks => $disks,
#boot => 'hd',
interfaces => hypervisor_interfaces($name,$internal_ip,$internal_mac,$external_ip,$external_mac,$external_net,$internal_method,$external_method,$interface_type),
interfaces => hypervisor_interfaces($net_interfaces),
autostart => $autostart,
require => [
Exec["/usr/local/bin/mkrootdisk.sh ${block_prefix}/${hypervisor::vm::root_vg}/${name}-disk"],
......@@ -272,7 +259,8 @@ libvirt::domain { $name:
#FIXME Libvirt::Nwfilter["${name}-internal"],
#FIXME Libvirt::Nwfilter["${name}-external"]
],
uuid => hypervisor_generate_uuid($name),
uuid => gen_consistent_uuid($name),
}
......
{
"name": "hypervisor",
"version": "0.0.1",
"author": "name",
"summary": "configures a hypervisor",
"license": "GPL-3.0",
"source": "https://git.puscii.nl/puppet1/puppet-hypervisor.git",
"project_page": "https://git.puscii.nl/puppet1/puppet-hypervisor",
"issues_url": "https://git.puscii.nl/puppet1/puppet-hypervisor/issues",
"dependencies": [
{
"name": "puppetlabs/stdlib",
"version_requirement": ">=3.0.0 < 7.0.0"
},
{
"name": "puppetlabs/concat",
"version_requirement": ">= 1.0.0 < 7.0.0"
},
{
"name": "puppetlabs/inifile",
"version_requirement": ">= 2.0.0 < 5.0.0"
}
],
"operatingsystem_support": [
{
"operatingsystem": "Debian",
"operatingsystemrelease": [
"10"
]
}
],
"requirements": [
{
"name": "puppet",
"version_requirement": ">=5.0.0 < 8.0.0"
}
],
"tags": [
"libvirt",
"kvm",
"drbd",
"virtualization"
],
"pdk-version": "1.18.1",
"template-url": "pdk-default#1.18.1",
"template-ref": "tags/1.18.1-0-g3d2e75c"
}
# Use default_module_facts.yml for module specific facts.
#
# Facts specified here will override the values provided by rspec-puppet-facts.
---
ipaddress: "172.16.254.254"
ipaddress6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA"
is_pe: false
macaddress: "AA:AA:AA:AA:AA:AA"
/home/user/notes/automation/puppet/code/modules/hypervisor
\ No newline at end of file
require 'spec_helper'
describe 'gen_consistent_uuid' do
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) { os_facts }
context 'with parameters' do
it { is_expected.to run.with_params('generate a uuid').and_return('ccb5557f-4aea-b88d-1a57-be7b3909e216') }
it { is_expected.to run.with_params('generate another uuid').and_return('57ca0a6e-d282-38a4-24fe-e7c8eb1c89b8') }
end
end
end
end
require 'spec_helper'
describe 'hypervisor_interfaces' do
on_supported_os.each do |os, os_facts|
context "on #{os}" do
let(:facts) { os_facts }
in_if = [
{
"ip" => "192.168.1.2",
"network" => "internal"
},
{
"ip" => "10.1.2.3",
"network" => "internal",
"mac" => "52:54:00:11:22:33"
}
]
out_if = [
{
"ip" => "192.168.1.2",
"network" => "internal",
"type" => "virtio",
"mac" => "52:54:00:c0:ca:1e"
},
{
"ip" => "10.1.2.3",
"network" => "internal",
"type" => "virtio",
"mac" => "52:54:00:11:22:33"
}
]
context 'with parameters' do
it {
is_expected.to run.with_params(in_if).and_return(out_if) }
end
end
end
end
# frozen_string_literal: true
RSpec.configure do |c|
c.mock_with :rspec
end
require 'puppetlabs_spec_helper/module_spec_helper'
require 'rspec-puppet-facts'
require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb'))
include RspecPuppetFacts
default_facts = {
puppetversion: Puppet.version,
facterversion: Facter.version,
}
default_fact_files = [
File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')),
File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')),
]
default_fact_files.each do |f|
next unless File.exist?(f) && File.readable?(f) && File.size?(f)
begin
default_facts.merge!(YAML.safe_load(File.read(f), [], [], true))
rescue => e
RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}"
end
end
# read default_facts and merge them over what is provided by facterdb
default_facts.each do |fact, value|
add_custom_fact fact, value
end
RSpec.configure do |c|
c.default_facts = default_facts
c.before :each do
# set to strictest setting for testing
# by default Puppet runs at warning level
Puppet.settings[:strict] = :warning
Puppet.settings[:strict_variables] = true
end
c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT']
c.after(:suite) do
RSpec::Puppet::Coverage.report!(0)
end
end
# Ensures that a module is defined
# @param module_name Name of the module
def ensure_module_defined(module_name)
module_name.split('::').reduce(Object) do |last_module, next_module|
last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false)
last_module.const_get(next_module, false)
end
end
# 'spec_overrides' from sync.yml will appear below this line
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment