Merge pull request 'feat: manage proxmox nodes' (#159) from neoloc/proxmox into develop

Reviewed-on: unkinben/puppet-prod#159
This commit is contained in:
2024-04-21 15:07:43 +09:30
33 changed files with 564 additions and 7 deletions
+50
View File
@@ -0,0 +1,50 @@
# profiles::proxmox::ceph
class profiles::proxmox::ceph {
# include params class
include profiles::proxmox::params
# localise some vars
$network = $profiles::proxmox::params::pve_ceph_network
$size = $profiles::proxmox::params::pve_ceph_size
$min_size = $profiles::proxmox::params::pve_ceph_minsize
# install ceph if it is enabled
if $profiles::proxmox::params::pve_ceph_install {
# initialise the cluster, but only on the clusterinit node and only if its not already initialised
if $profiles::proxmox::params::pve_clusterinit_master and ! $facts['pve_ceph_initialised']{
exec { 'pveceph_init':
command => "/usr/bin/pveceph init --network ${network} --size ${size} --min_size ${min_size}",
user => 'root',
}
}
if $facts['pve_ceph_initialised'] {
# create monitors
if $profiles::proxmox::params::pve_ceph_mon {
# only when its not already a monitor
if ! $facts['is_pveceph_mon'] {
exec { 'pveceph_mon':
command => '/usr/bin/pveceph mon create',
user => 'root',
}
}
}
# create managers
if $profiles::proxmox::params::pve_ceph_mgr {
# only when its not already a manager
if ! $facts['is_pveceph_mgr'] {
exec { 'pveceph_mgr':
command => '/usr/bin/pveceph mgr create',
user => 'root',
}
}
}
}
}
}
@@ -0,0 +1,41 @@
# profiles::proxmox::clusterinit
class profiles::proxmox::clusterinit {
# include params class
include profiles::proxmox::params
# localise some vars
$clusterinit_master = $profiles::proxmox::params::pve_clusterinit_master
$clustername = $profiles::proxmox::params::pve_cluster
$membersrole = $profiles::proxmox::params::pve_members_role
# if this is the cluster master
if $clusterinit_master {
# and its not a member of a cluster yet
if ! $facts['pve_cluster_member'] {
# initialise a cluster
exec {'pve_init_cluster':
command => "/usr/bin/pvecm create ${clustername}",
unless => 'pvecm status',
timeout => 60,
}
}
}
$servers_array = sort(query_nodes(
"enc_role='${membersrole}' and country='${facts['country']}' and region='${facts['region']}'",
'networking.fqdn'
))
if ! $profiles::proxmox::params::pve_clusterinit_master {
if !empty($servers_array) {
notify { "Cluster ${profiles::proxmox::params::pve_cluster} detected, proceeding to join...":
}
} else {
notify { "No cluster flag found for ${profiles::proxmox::params::pve_cluster}, not attempting to join":
}
}
}
}
@@ -0,0 +1,74 @@
# profiles::proxmox::clusterjoin
class profiles::proxmox::clusterjoin {
# include params class
include profiles::proxmox::params
# localise some vars
$clusterinit_master = $profiles::proxmox::params::pve_clusterinit_master
$clustername = $profiles::proxmox::params::pve_cluster
$membersrole = $profiles::proxmox::params::pve_members_role
$root_password = $profiles::proxmox::params::root_password
# query puppetdb for list of cluster members
$members_array = sort(query_nodes(
"enc_role='${membersrole}' and \
country='${facts['country']}' and \
region='${facts['region']}' and \
pve_cluster.cluster_name='${clustername}'",
'networking.fqdn'
))
# check if the pve kernerl is running
if $facts['kernelrelease'] == $profiles::proxmox::params::pve_kernel_release {
# if this is the cluster master
if $clusterinit_master {
# there are no cluster members in puppetdb
if empty($members_array) {
# and this host isnt already in a cluster by itself
if ! $facts['pve_cluster'] {
# initialise a cluster
exec {'pve_init_cluster':
command => "/usr/bin/pvecm create ${clustername}",
unless => 'pvecm status',
timeout => 60,
}
}
}
}
# for non-masters
if ! $clusterinit_master {
# if there are already members of the cluster
if !empty($members_array) {
# and this host isnt already in a cluster
if ! $facts['pve_cluster'] {
# create an expect script to join the cluster
file { '/usr/local/bin/join_pvecluster.expect':
ensure => file,
owner => 'root',
mode => '0755',
content => template('profiles/proxmox/join_pvecluster.erb'),
}
exec { 'pve_join_cluster':
command => "/usr/local/bin/join_pvecluster.expect '${root_password.unwrap}' '${members_array[0]}'",
require => [File['/usr/local/bin/join_pvecluster.expect'], Package['expect']],
unless => "/usr/bin/pvesh nodes | grep -q '${facts['networking']['hostname']}'",
user => 'root',
}
}
} else {
notify { "No initialised cluster found for ${clustername}, not attempting to join":
}
}
}
}
}
+19
View File
@@ -0,0 +1,19 @@
# profiles::proxmox::config
class profiles::proxmox::config {
# include params class
include profiles::proxmox::params
# localise some vars
$clusterinit_master = $profiles::proxmox::params::pve_clusterinit_master
# create pve_facts file
file {'/opt/puppetlabs/facter/facts.d/pve_facts.yaml':
ensure => 'file',
owner => 'root',
group => 'root',
mode => '0600',
content => template('profiles/proxmox/pve_facts.yaml.erb')
}
}
+16
View File
@@ -0,0 +1,16 @@
# proxmox::
class profiles::proxmox::init {
#include profiles::proxmox::params
include profiles::proxmox::repos
include profiles::proxmox::install
include profiles::proxmox::clusterjoin
include profiles::proxmox::ceph
include profiles::proxmox::config
Class['profiles::proxmox::repos']
-> Class['profiles::proxmox::install']
-> Class['profiles::proxmox::clusterjoin']
-> Class['profiles::proxmox::ceph']
-> Class['profiles::proxmox::config']
}
@@ -0,0 +1,58 @@
# profiles::proxmox::install
class profiles::proxmox::install {
# include params class
include profiles::proxmox::params
# install the pve kernel
package { 'proxmox-default-kernel':
ensure => $profiles::proxmox::params::pve_kernel_version,
notify => Reboot['after_run'],
require => Apt::Source['proxmox'],
}
# reboot into the new kernel
reboot { 'after_run':
apply => finished,
}
if $facts['kernelrelease'] == $profiles::proxmox::params::pve_kernel_release {
# install pve
ensure_packages($profiles::proxmox::params::pve_packages_install, { ensure => 'present', require => Apt::Source['proxmox']})
# remove the old linux kernel metapackage
ensure_packages($profiles::proxmox::params::pve_packages_remove, { ensure => 'absent' })
# install ceph package if requested
if $profiles::proxmox::params::pve_ceph_install {
ensure_packages($profiles::proxmox::params::pve_packages_ceph, { ensure => 'present', require => Apt::Source['ceph'] })
}
# cleanup the old kernel packages
exec { 'remove-linux-kernel-packages':
command => '/usr/bin/apt-get purge -y $(/usr/bin/dpkg --list | /bin/grep "linux-image-6.1" | /usr/bin/awk \'{ print $2 }\')',
onlyif => '/usr/bin/dpkg --list | /bin/grep -q "linux-image-6.1"',
path => ['/usr/bin', '/bin', '/sbin'],
refreshonly => true,
}
# update grup
exec { 'update-grub':
command => '/usr/sbin/update-grub',
path => ['/usr/bin', '/bin', '/sbin'],
refreshonly => true,
}
# update grub after removing kernel packages only
Exec['remove-linux-kernel-packages'] ~> Exec['update-grub']
# prepare for SDN
file_line { 'source-network-interfaces-d':
path => '/etc/network/interfaces',
line => 'source /etc/network/interfaces.d/*',
match => '^source /etc/network/interfaces.d/\*$',
append_on_no_match => true,
}
}
}
+42
View File
@@ -0,0 +1,42 @@
# profiles::proxmox::params
class profiles::proxmox::params (
Sensitive[String] $root_password = Sensitive(lookup('profiles::accounts::root::password')),
String $pve_members_role = 'roles::infra::proxmox::node',
String $pve_kernel_version = '1.0.1',
String $pve_kernel_release = '6.5.13-5-pve',
String $pve_cluster = "${::facts['country']}-${::facts['region']}",
Boolean $pve_clusterinit_master = false,
Boolean $pve_ceph_repos = false,
Boolean $pve_ceph_install = false,
Boolean $pve_ceph_mon = false,
Boolean $pve_ceph_mgr = false,
Boolean $pve_ceph_osd = false,
String $pve_ceph_release = 'quincy',
Integer $pve_ceph_size = 3,
Integer $pve_ceph_minsize = 2,
Variant[
Undef,
Stdlib::IP::Address::V4::CIDR
] $pve_ceph_network = undef,
Array $pve_packages_install = [
'proxmox-ve',
'postfix',
'open-iscsi',
'frr-pythontools'
],
Array $pve_packages_remove = [
'os-prober',
'linux-image-amd64'
],
Array $pve_packages_ceph = [
'ceph',
'ceph-common',
'ceph-fuse',
'ceph-mds',
'ceph-volume',
'gdisk',
'nvme-cli'
]
){
}
+37
View File
@@ -0,0 +1,37 @@
# profiles::proxmox::repos
class profiles::proxmox::repos {
# include params class
include profiles::proxmox::params
$codename = $facts['os']['distro']['codename']
exec { 'download-proxmox-gpg-key':
command => "/usr/bin/wget https://enterprise.proxmox.com/debian/proxmox-release-${codename}.gpg -O /etc/apt/trusted.gpg.d/proxmox-release-${codename}.gpg",
creates => "/etc/apt/trusted.gpg.d/proxmox-release-${codename}.gpg",
path => ['/usr/bin', '/bin'],
require => File['/etc/apt/trusted.gpg.d/'],
}
file { '/etc/apt/trusted.gpg.d/':
ensure => 'directory',
}
apt::source { 'proxmox':
location => 'http://download.proxmox.com/debian/pve',
repos => 'pve-no-subscription',
include => {
src => false,
},
}
if $profiles::proxmox::params::pve_ceph_repos {
apt::source { 'ceph':
location => "http://download.proxmox.com/debian/ceph-${profiles::proxmox::params::pve_ceph_release}",
repos => 'no-subscription',
include => {
src => false,
},
}
}
}
+1 -6
View File
@@ -1,15 +1,10 @@
# /etc/hosts file managed by Puppet
# The following lines are desirable for IPv4 capable hosts
127.0.0.1 <%= @fqdn %> <%= @hostname %>
<%= @facts['networking']['ip'] %> <%= @fqdn %> <%= @hostname %>
127.0.0.1 localhost.localdomain localhost
127.0.0.1 localhost4.localdomain4 localhost4
# The following lines are desirable for IPv6 capable hosts
::1 <%= @fqdn %> <%= @hostname %>
::1 localhost.localdomain localhost
::1 localhost6.localdomain6 localhost6
<% @additional_hosts.each do |host| -%>
<%= host['ip'] %> <%= host['hostname'] %> <%= host['aliases'].join(' ') if host['aliases'] %>
<% end -%>
@@ -0,0 +1,11 @@
#!/usr/bin/expect -f
set timeout -1
set password [lindex $argv 0]
set ip [lindex $argv 1]
spawn pvecm add $ip
expect "Please enter superuser (root) password for"
send "$password\r"
expect "The authenticity of host"
send "yes\r"
expect eof
@@ -0,0 +1,2 @@
---
pve_clusterinit_master: <%= @clusterinit_master %>