diff --git a/manifests/deploy.pp b/manifests/deploy.pp index b39afe6..d03d68e 100644 --- a/manifests/deploy.pp +++ b/manifests/deploy.pp @@ -5,14 +5,31 @@ # class n1k_vsm::deploy { + require n1k_vsm + include n1k_vsm + #ensure tap interfaces and deploy the vsm $ctrltap = 'vsm-ctrl0' $mgmttap = 'vsm-mgmt0' $pkttap = 'vsm-pkt0' + # Validate and get the array of digits for the vsm_mac_base (or use default) + # Using _vmb as the name for the final string to increase readability + $tmp_mac_base = regsubst($n1k_vsm::vsm_mac_base, '[^0-9a-fA-F]+', '') + if (inline_template('<%= @tmp_mac_base.length %>') < 7) { + $vmb = split('005dc79', '') + } else { + $vmb = split($tmp_mac_base, '') + } + + # Generate MACs for VSM + $ctrlmac = "52:54:${vmb[0]}${vmb[1]}:${vmb[2]}${vmb[3]}:${vmb[4]}${vmb[5]}:${vmb[6]}1" + $mgmtmac = "52:54:${vmb[0]}${vmb[1]}:${vmb[2]}${vmb[3]}:${vmb[4]}${vmb[5]}:${vmb[6]}2" + $pktmac = "52:54:${vmb[0]}${vmb[1]}:${vmb[2]}${vmb[3]}:${vmb[4]}${vmb[5]}:${vmb[6]}3" + exec { 'Exec_create_disk': command => "/usr/bin/qemu-img create -f raw ${n1k_vsm::diskfile} ${n1k_vsm::disksize}G", - unless => "/usr/bin/virsh list --all | grep -c ${n1k_vsm::vsmname}", + creates => $n1k_vsm::diskfile, } $targetxmlfile = "/var/spool/cisco/vsm/vsm_${n1k_vsm::vsm_role}_deploy.xml" @@ -21,19 +38,49 @@ class n1k_vsm::deploy owner => 'root', group => 'root', mode => '0666', + seltype => 'virt_content_t', content => template('n1k_vsm/vsm_vm.xml.erb'), require => Exec['Exec_create_disk'], } - exec { 'Exec_Define_VSM': - command => "/usr/bin/virsh define ${targetxmlfile}", - unless => "/usr/bin/virsh list --all | grep -c ${n1k_vsm::vsmname}", - } + # Don't start VSM if this is pacemaker controlled deployment + if !($n1k_vsm::pacemaker_control) { + exec { 'Exec_Define_VSM': + command => "/usr/bin/virsh define ${targetxmlfile}", + unless => "/usr/bin/virsh list --all | grep -c ${n1k_vsm::vsmname}", + require => File['File_Target_XML_File'], + } - exec { 'Exec_Launch_VSM': - command => "/usr/bin/virsh start ${n1k_vsm::vsmname}", - unless => "/usr/bin/virsh list --all | grep ${n1k_vsm::vsmname} | grep -c running", - } + exec { 'Exec_Launch_VSM': + command => "/usr/bin/virsh start ${n1k_vsm::vsmname}", + unless => ("/usr/bin/virsh list --all | grep ${n1k_vsm::vsmname} | grep -c running"), + require => Exec['Exec_Define_VSM'], + } + } else { + # For pacemker controlled deployment, set up the secondary VSM as well + # ensure tap interfaces and deploy the vsm + $ctrltap_s = 'vsm-ctrl1' + $mgmttap_s = 'vsm-mgmt1' + $pkttap_s = 'vsm-pkt1' + # Generate MACs + $ctrlmac_s = "52:54:${vmb[0]}${vmb[1]}:${vmb[2]}${vmb[3]}:${vmb[4]}${vmb[5]}:${vmb[6]}4" + $mgmtmac_s = "52:54:${vmb[0]}${vmb[1]}:${vmb[2]}${vmb[3]}:${vmb[4]}${vmb[5]}:${vmb[6]}5" + $pktmac_s = "52:54:${vmb[0]}${vmb[1]}:${vmb[2]}${vmb[3]}:${vmb[4]}${vmb[5]}:${vmb[6]}6" - Exec['Exec_create_disk'] -> File['File_Target_XML_File'] -> Exec['Exec_Define_VSM'] -> Exec['Exec_Launch_VSM'] + exec { 'Exec_create_disk_Secondary': + command => "/usr/bin/qemu-img create -f raw ${n1k_vsm::diskfile_s} ${n1k_vsm::disksize}G", + creates => $n1k_vsm::diskfile_s, + } + + $targetxmlfile_s = "/var/spool/cisco/vsm/vsm_${n1k_vsm::vsm_role_s}_deploy.xml" + file { 'File_Target_XML_File_Secondary': + path => $targetxmlfile_s, + owner => 'root', + group => 'root', + mode => '0666', + seltype => 'virt_content_t', + content => template('n1k_vsm/vsm_vm_secondary.xml.erb'), + require => Exec['Exec_create_disk_Secondary'], + } + } } diff --git a/manifests/init.pp b/manifests/init.pp index 13307a4..261b30c 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -36,6 +36,19 @@ # [*n1kv_version*] # (required) Version of the Nexus1000v VSM # +# [*pacemaker_control*] +# (optional) Set to determine if pacemaker will control the VSM. If true will deploy both +# primary and secondary VSMs on all nodes and will not start VSM. Defaults to false and +# thus is optional unless this functionality is being used. +# +# [*existing_bridge*] +# (required) If VSM should be installed behind an existing bridge, this should be set to +# true and the bridge name should be provided in phy_if_bridge. +# +# [*vsm_mac_base*] +# (optional) If set, provides randomization for the MAC addresses for the VSM VM(s). +# Should be a (random) hexadecimal number of at least 7 digits (more is fine). +# class n1k_vsm( $n1kv_source = '', $n1kv_version = 'latest', @@ -47,6 +60,9 @@ class n1k_vsm( $vsm_mgmt_ip, $vsm_mgmt_netmask, $vsm_mgmt_gateway, + $pacemaker_control = false, + $existing_bridge = false, + $vsm_mac_base = '' ) { if($::osfamily != 'Redhat') { @@ -55,6 +71,15 @@ class n1k_vsm( fail("Unsupported osfamily ${::osfamily}") } + # Ensure role is set to primary for pacemaker controlled deployment + # Additionally setup the extra variables for the secondary VSM + if ($n1k_vsm::pacemaker_control) { + $vsm_role_s = 'secondary' + $vsmname_s = 'vsm-s' + $imgfile_s = "/var/spool/cisco/vsm/${vsm_role_s}_repacked.iso" + $diskfile_s = "/var/spool/cisco/vsm/${vsm_role_s}_disk" + } + if ($n1k_vsm::vsm_role == 'primary') or ($n1k_vsm::vsm_role == 'standalone') { $vsmname = 'vsm-p' $mgmtip = $vsm_mgmt_ip @@ -73,7 +98,9 @@ class n1k_vsm( $disksize = 4 $imgfile = "/var/spool/cisco/vsm/${n1k_vsm::vsm_role}_repacked.iso" $diskfile = "/var/spool/cisco/vsm/${n1k_vsm::vsm_role}_disk" - $ovsbridge = 'vsm-br' + + #Set bridge name properly + $ovsbridge = 'vsm-br' #VSM installation will be done only once. Will not respond to puppet sync $_phy_if_bridge = regsubst($n1k_vsm::phy_if_bridge, '[.:-]+', '_', 'G') diff --git a/manifests/pkgprep_ovscfg.pp b/manifests/pkgprep_ovscfg.pp index 073fd98..5705a3d 100644 --- a/manifests/pkgprep_ovscfg.pp +++ b/manifests/pkgprep_ovscfg.pp @@ -19,7 +19,7 @@ class n1k_vsm::pkgprep_ovscfg # VSM dependent packages installation section package { 'Package_qemu-kvm': ensure => installed, - name => 'qemu-kvm', + name => 'qemu-kvm-rhev', } package {'Package_libvirt': @@ -64,8 +64,11 @@ class n1k_vsm::pkgprep_ovscfg notify { "Debug br ${n1k_vsm::ovsbridge} intf ${n1k_vsm::phy_if_bridge} ." : withpath => true } notify { "Debug ${n1k_vsm::vsmname} ip ${n1k_vsm::phy_ip_addr} mask ${n1k_vsm::phy_ip_mask} gw_intf ${n1k_vsm::gw_intf}" : withpath => true } - # Check if we've already configured the ovs - if $n1k_vsm::gw_intf != $n1k_vsm::ovsbridge { + $_ovsbridge = regsubst($n1k_vsm::ovsbridge, '[.:-]+', '_', 'G') + $_ovsbridge_mac = inline_template("<%= scope.lookupvar('::macaddress_${_ovsbridge}') %>") + + # Check if we've already configured the vsm bridge, skip configuration if so + if ($_ovsbridge_mac == '') { # Modify Ovs bridge inteface configuation file augeas { 'Augeas_modify_ifcfg-ovsbridge': name => $n1k_vsm::ovsbridge, @@ -87,47 +90,50 @@ class n1k_vsm::pkgprep_ovscfg 'set USERCTL no', ], } - - # Modify Physical Interface config file - augeas { 'Augeas_modify_ifcfg-phy_if_bridge': - name => $n1k_vsm::phy_if_bridge, - context => "/files/etc/sysconfig/network-scripts/ifcfg-${n1k_vsm::phy_if_bridge}", - changes => [ - 'set TYPE OVSPort', - "set DEVICE ${n1k_vsm::phy_if_bridge}", - 'set DEVICETYPE ovs', - "set OVS_BRIDGE ${n1k_vsm::ovsbridge}", - 'set NM_CONTROLLED no', - 'set BOOTPROTO none', - 'set ONBOOT yes', - "set NAME ${n1k_vsm::phy_if_bridge}", - 'set DEFROUTE no', - 'set IPADDR ""', - 'rm NETMASK', - 'rm GATEWAY', - 'set USERCTL no', - ], - } - exec { 'Flap_n1kv_phy_if': - command => "/sbin/ifdown ${n1k_vsm::phy_if_bridge} && /sbin/ifup ${n1k_vsm::phy_if_bridge}", - require => augeas['Augeas_modify_ifcfg-phy_if_bridge'], - } exec { 'Flap_n1kv_bridge': command => "/sbin/ifdown ${n1k_vsm::ovsbridge} && /sbin/ifup ${n1k_vsm::ovsbridge}", - require => augeas['Augeas_modify_ifcfg-ovsbridge'], + require => Augeas['Augeas_modify_ifcfg-ovsbridge'], } - # Make sure that networking comes fine after reboot- add init file and restart networking - file { 'Create_Init_File': - replace => 'yes', - path => '/etc/init.d/n1kv', - owner => 'root', - group => 'root', - mode => '0775', - source => 'puppet:///modules/n1k_vsm/n1kv', - require => exec['Flap_n1kv_phy_if', 'Flap_n1kv_bridge'], - notify => Service['Service_network'], + + if !($n1k_vsm::existing_bridge) { + # If there isn't an existing bridge, the interface is a port, and we + # need to add it to vsm-br + # Modify Physical Interface config file + augeas { 'Augeas_modify_ifcfg-phy_if_bridge': + name => $n1k_vsm::phy_if_bridge, + context => "/files/etc/sysconfig/network-scripts/ifcfg-${n1k_vsm::phy_if_bridge}", + changes => [ + 'set TYPE OVSPort', + "set DEVICE ${n1k_vsm::phy_if_bridge}", + 'set DEVICETYPE ovs', + "set OVS_BRIDGE ${n1k_vsm::ovsbridge}", + 'set NM_CONTROLLED no', + 'set BOOTPROTO none', + 'set ONBOOT yes', + "set NAME ${n1k_vsm::phy_if_bridge}", + 'set DEFROUTE no', + 'set IPADDR ""', + 'rm NETMASK', + 'rm GATEWAY', + 'set USERCTL no', + ], + } + exec { 'Flap_n1kv_phy_if': + command => "/sbin/ifdown ${n1k_vsm::phy_if_bridge} && /sbin/ifup ${n1k_vsm::phy_if_bridge}", + require => Augeas['Augeas_modify_ifcfg-phy_if_bridge'], + } + } else { + # If there is an existing bridge- create patch ports to connect vsm-br to it + exec { 'Create_patch_port_on_existing_bridge': + command => "/bin/ovs-vsctl --may-exist add-port ${n1k_vsm::phy_if_bridge} ${n1k_vsm::phy_if_bridge}-${n1k_vsm::ovsbridge} -- set Interface ${n1k_vsm::phy_if_bridge}-${n1k_vsm::ovsbridge} type=patch options:peer=${n1k_vsm::ovsbridge}-${n1k_vsm::phy_if_bridge}", + require => Exec['Flap_n1kv_bridge'], + } + exec { 'Create_patch_port_on_vsm_bridge': + command => "/bin/ovs-vsctl --may-exist add-port ${n1k_vsm::ovsbridge} ${n1k_vsm::ovsbridge}-${n1k_vsm::phy_if_bridge} -- set Interface ${n1k_vsm::ovsbridge}-${n1k_vsm::phy_if_bridge} type=patch options:peer=${n1k_vsm::phy_if_bridge}-${n1k_vsm::ovsbridge}", + require => Exec['Flap_n1kv_bridge'], + } } - } # endif of if "${n1k_vsm::gw_intf}" != "${n1k_vsm::ovsbridge}" + } # endif of if "${n1k_vsm::gw_intf}" != "${n1k_vsm::ovsbridge}" or ($n1k_vsm::existing_bridge == 'true') } 'Ubuntu': { } diff --git a/manifests/vsmprep.pp b/manifests/vsmprep.pp index f704666..d356a06 100644 --- a/manifests/vsmprep.pp +++ b/manifests/vsmprep.pp @@ -35,12 +35,9 @@ class n1k_vsm::vsmprep } } else { $vsmimage_uri = 'unspec' + $vsm_path = '/opt/cisco/vsm' } -# exec { 'Prev_VSM': -# command => "/bin/rm -f /var/spool/cisco/vsm/* || /bin/true", -# } - if $vsmimage_uri == 'file' { #specify location on target-host where image file will be downloaded to. file { $vsmtgtimg: @@ -63,8 +60,9 @@ class n1k_vsm::vsmprep } } package {'nexus-1000v-iso': - ensure => $n1k_vsm::n1kv_version, - name => 'nexus-1000v-iso' + ensure => $n1k_vsm::n1kv_version, + name => 'nexus-1000v-iso', + provider => 'yum', } } @@ -80,8 +78,15 @@ class n1k_vsm::vsmprep # Now generate ovf xml file and repackage the iso exec { 'Exec_VSM_Repackage_Script': - command => "/tmp/repackiso.py -i${vsm_path}/n1000v-dk9.${n1k_vsm::n1kv_version}.iso -d${n1k_vsm::vsm_domain_id} -n${n1k_vsm::vsmname} -m${n1k_vsm::mgmtip} -s${n1k_vsm::mgmtnetmask} -g${n1k_vsm::mgmtgateway} -p${n1k_vsm::vsm_admin_passwd} -r${n1k_vsm::vsm_role} -f/var/spool/cisco/vsm/${n1k_vsm::vsm_role}_repacked.iso ", - unless => "/usr/bin/virsh list --all | grep -c ${n1k_vsm::vsmname}", + command => "/tmp/repackiso.py -i${vsm_path}/n1000v-dk9.${n1k_vsm::n1kv_version}.iso -d${n1k_vsm::vsm_domain_id} -n${n1k_vsm::vsmname} -m${n1k_vsm::mgmtip} -s${n1k_vsm::mgmtnetmask} -g${n1k_vsm::mgmtgateway} -p${n1k_vsm::vsm_admin_passwd} -r${n1k_vsm::vsm_role} -f/var/spool/cisco/vsm/${n1k_vsm::vsm_role}_repacked.iso", + creates => "/var/spool/cisco/vsm/${n1k_vsm::vsm_role}_repacked.iso", } + # If we're under pacemaker_control, create a secondary VSM iso as well + if ($n1k_vsm::pacemaker_control) { + exec { 'Exec_VSM_Repackage_Script_secondary': + command => "/tmp/repackiso.py -i${vsm_path}/n1000v-dk9.${n1k_vsm::n1kv_version}.iso -d${n1k_vsm::vsm_domain_id} -n${n1k_vsm::vsmname_s} -m${n1k_vsm::mgmtip} -s${n1k_vsm::mgmtnetmask} -g${n1k_vsm::mgmtgateway} -p${n1k_vsm::vsm_admin_passwd} -r${n1k_vsm::vsm_role_s} -f/var/spool/cisco/vsm/${n1k_vsm::vsm_role_s}_repacked.iso", + creates => "/var/spool/cisco/vsm/${n1k_vsm::vsm_role_s}_repacked.iso", + } + } } diff --git a/templates/vsm_vm.xml.erb b/templates/vsm_vm.xml.erb index 82a2a01..7096724 100644 --- a/templates/vsm_vm.xml.erb +++ b/templates/vsm_vm.xml.erb @@ -41,6 +41,9 @@ + <% if scope.lookupvar('n1k_vsm::pacemaker_control') == true %> + + <% end %>
@@ -49,6 +52,9 @@ + <% if scope.lookupvar('n1k_vsm::pacemaker_control') == true %> + + <% end %>
@@ -57,6 +63,9 @@ + <% if scope.lookupvar('n1k_vsm::pacemaker_control') == true %> + + <% end %>
diff --git a/templates/vsm_vm_secondary.xml.erb b/templates/vsm_vm_secondary.xml.erb new file mode 100644 index 0000000..cbd237b --- /dev/null +++ b/templates/vsm_vm_secondary.xml.erb @@ -0,0 +1,92 @@ + + <%= scope.lookupvar('n1k_vsm::vsmname_s') %> + <%= scope.lookupvar('n1k_vsm::memory') %> + <%= scope.lookupvar('n1k_vsm::vcpu') %> + + + hvm + + + + + + + + destroy + restart + restart + + + /usr/libexec/qemu-kvm + + + '/> + + + + + + '/> + + + + + + +
+ + + + '/> + + + + <% if scope.lookupvar('n1k_vsm::pacemaker_control') == true %> + + <% end %> +
+ + + + '/> + + + + <% if scope.lookupvar('n1k_vsm::pacemaker_control') == true %> + + <% end %> +
+ + + + '/> + + + + <% if scope.lookupvar('n1k_vsm::pacemaker_control') == true %> + + <% end %> +
+ + + + + + + + +