From 95eeb73c4c3cb54c337cf20f369c79ddbe2823a9 Mon Sep 17 00:00:00 2001 From: Ricardo Carrillo Cruz Date: Wed, 15 Jul 2015 07:39:05 +0000 Subject: [PATCH] Add bifrost manifest Bifrost is a set of Ansible playbooks to install Ironic in standalone mode and enrolling and deploying baremetal servers Change-Id: I1f31c8a59d82112d998fb3555c9f55d5c850093d --- .fixtures.yml | 1 + examples/ironic.pp | 38 ++++++ manifests/bifrost.pp | 202 ++++++++++++++++++++++++++++ metadata.json | 3 +- spec/classes/ironic_bifrost_spec.rb | 84 ++++++++++++ templates/baremetal.json.erb | 3 + templates/group_vars_all.erb | 44 ++++++ 7 files changed, 374 insertions(+), 1 deletion(-) create mode 100644 manifests/bifrost.pp create mode 100644 spec/classes/ironic_bifrost_spec.rb create mode 100644 templates/baremetal.json.erb create mode 100644 templates/group_vars_all.erb diff --git a/.fixtures.yml b/.fixtures.yml index 718df572..152041a7 100644 --- a/.fixtures.yml +++ b/.fixtures.yml @@ -9,5 +9,6 @@ fixtures: 'openstacklib': 'git://github.com/stackforge/puppet-openstacklib.git' 'postgresql': 'git://github.com/puppetlabs/puppet-postgresql.git' 'stdlib': 'git://github.com/puppetlabs/puppetlabs-stdlib.git' + 'vcsrepo': 'git://github.com/puppetlabs/puppetlabs-vcsrepo.git' symlinks: 'ironic': "#{source_dir}" diff --git a/examples/ironic.pp b/examples/ironic.pp index 71d5c268..1ced6e6e 100644 --- a/examples/ironic.pp +++ b/examples/ironic.pp @@ -30,6 +30,33 @@ $rabbit_port = '5672' $glance_api_servers = 'glance:9292' $deploy_kernel = 'glance://deploy_kernel_uuid' $deploy_ramdisk = 'glance://deploy_ramdisk_uuid' +$baremetal_json_hosts = ' + "ironic-bm-test.bifrost.example": { + "ansible_ssh_host": "1.1.1.1", + "uuid": "11111111-1111-1111-1111-111111111111", + "driver_info": { + "power": { + "ipmi_address": "10.0.0.1", + "ipmi_username": "admin", + "ipmi_password": "pass" + }, + }, + "nics": [ + { + "mac": "ff:ff:ff:ff:ff:ff" + } + ], + "driver": "agent_ipmitool", + "ipv4_address": "1.1.1.1", + "properties": { + "cpu_arch": "x86_64", + "ram": null, + "disk_size": null, + "cpus": null + }, + "name": "ironic-bm-test.bifrost.example" + } +' node 'db' { @@ -79,3 +106,14 @@ node controller { } } + +node bifrost-controller { + + class { '::ironic::bifrost': + network_interface => 'eth1', + ironic_db_password => 'changeme', + mysql_password => 'changemetoo', + baremetal_json_hosts => $baremetal_json_hosts, + } + +} diff --git a/manifests/bifrost.pp b/manifests/bifrost.pp new file mode 100644 index 00000000..34dcd6b2 --- /dev/null +++ b/manifests/bifrost.pp @@ -0,0 +1,202 @@ +# Copyright 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. + +# == Class: ironic::bifrost +# +# Installs and configures Bifrost +# Bifrost is a set of Ansible playbooks that automates the task of deploying a +# base image onto a set of known hardware using Ironic. It provides modular +# utility for one-off operating system deployment with as few operational requirements +# as reasonably possible. +# Bifrost also allows to install Ironic in a stand-alone fashion. In this kind of setup, +# neither Keystone nor Neutron is installed, and dnsmasq is used to provide PXE booting. +# +# [*ironic_db_password*] +# (required) The Ironic DB password +# +# [*mysql_password*] +# (required) The mysql server password +# +# [*baremetal_json_hosts*] +# (required) Baremetal hosts in JSON format, will be included in baremetal.json +# +# [*git_source_repo*] +# (optional) Git repository location for pulling Bifrost +# Defaults to 'https://git.openstack.org/openstack/bifrost' +# +# [*revision*] +# (optional) The branch or commit to checkout on Bifrost repository +# Defaults to 'master' +# +# [*ensure*] +# (optional) Ensure value for cloning the Bifrost repository. +# This is a pass-thru variable for vcsrepo, acceptable values are +# present/bare/absent/latest +# Typically, you may want to set this value to either present or absent and use +# revision for setting the branch or commit to clone. +# Defaults to 'present' +# +# [*revision*] +# (optional) The branch or commit to checkout on Bifrost repository +# Defaults to 'master' +# +# [*git_dest_repo_folder*] +# (optional) Folder to clone the Bifrost git repository +# Defaults to '/opt/stack/bifrost' +# +# [*ironic_url*] +# (optional) The URL of the Ironic server +# Defaults to '"http://localhost:6385"' +# +# [*network_interface*] +# (optional) The network interface DHCP will serve requests on +# Defaults to '"virbr0"' +# +# [*testing*] +# (optional) If true, Ironic will provision libvirt and VMs instead of baremetal +# Defaults to 'false' +# +# [*testing_user*] +# (optional) VM default user in case testing is enabled +# Defaults to 'ubuntu' +# +# [*http_boot_folder*] +# (optional) gPXE folder location for HTTP PXE boot +# Defaults to '/httpboot' +# +# [*nginx_port*] +# (optional) NGINX HTTP port +# Defaults to 8080 + +# [*ssh_public_key_path*] +# (optional) SSH public key location, this will be injected in provisioned servers +# Defaults to '"{{ ansible_env.HOME }}/.ssh/id_rsa.pub"' +# +# [*deploy_kernel*] +# (optional) Kernel to PXE boot from +# Defaults to '"{{http_boot_folder}}/coreos_production_pxe.vmlinuz"' +# +# [*deploy_ramdisk*] +# (optional) Ramdisk to load after kernel boot +# Defaults to '"{{http_boot_folder}}/coreos_production_pxe_image-oem.cpio.gz"' +# +# [*deploy_kernel_url*] +# (optional) Kernel URL +# Defaults to '"http://{{ hostvars[inventory_hostname][\'ansible_\' + network_interface][\'ipv4\'][\'address\'] }}:{{nginx_port}}/coreos_production_pxe.vmlinuz"' +# +# [*deploy_ramdisk_url*] +# (optional) Ramdisk URL +# Defaults to '"http://{{ hostvars[inventory_hostname][\'ansible_\' + network_interface][\'ipv4\'][\'address\'] }}:{{nginx_port}}/coreos_production_pxe_image-oem.cpio.gz"' +# +# [*deploy_image_filename*] +# (optional) Deploy image filename +# Defaults to '"deployment_image.qcow2"' +# +# [*deploy_image*] +# (optional) URL for the deployment image +# Defaults to '"{{http_boot_folder}}/{{deploy_image_filename}}"' +# +# [*create_image_via_dib*] +# (optional) Flag to enable/disable image creation with diskimage-builder +# Defaults to 'true' +# +# [*transform_boot_image*] +# (optional) Flag to prepend a partition image with boot sector and partition table +# Defaults to 'false' +# +# [*node_default_network_interface*] +# (optional) Default network interface to configure with configdrive settings +# Defaults to 'eth0' +# +# [*ipv4_subnet_mask*] +# (optional) Subnet mask for configured NIC +# Defaults to '255.255.255.0' +# +# [*ipv4_gateway*] +# (optional) Gateway for configured NIC +# Defaults to '192.168.1.1' +# +# [*ipv4_nameserver*] +# (optional) Nameserver for DNS configuration +# Defaults to '8.8.8.8' +# +# [*network_mtu*] +# (optional) MTU for configured NIC +# Defaults to '1500' +# +# [*dhcp_pool_start*] +# (optional) Dnsmasq DHCP pool start +# Defaults to '192.168.1.200' +# +# [*dhcp_pool_end*] +# (optional) Dnsmasq DHCP pool end +# Defaults to '192.168.1.250' +# +# [*ipmi_bridging*] +# (optional) Flag to enable/disable IPMI bridging +# Defaults to 'no' + +class ironic::bifrost ( + $ironic_db_password, + $mysql_password, + $baremetal_json_hosts, + $git_source_repo = 'https://git.openstack.org/openstack/bifrost', + $ensure = present, + $revision = 'master', + $git_dest_repo_folder = '/opt/stack/bifrost', + $ironic_url = '"http://localhost:6385/"', + $network_interface = '"virbr0"', + $testing = false, + $testing_user = 'ubuntu', + $http_boot_folder = '/httpboot', + $nginx_port = 8080, + $ssh_public_key_path = '"{{ ansible_env.HOME }}/.ssh/id_rsa.pub"', + $deploy_kernel = '"{{http_boot_folder}}/coreos_production_pxe.vmlinuz"', + $deploy_ramdisk = '"{{http_boot_folder}}/coreos_production_pxe_image-oem.cpio.gz"', + $deploy_kernel_url = '"http://{{ hostvars[inventory_hostname][\'ansible_\' + network_interface][\'ipv4\'][\'address\'] }}:{{nginx_port}}/coreos_production_pxe.vmlinuz"', + $deploy_ramdisk_url = '"http://{{ hostvars[inventory_hostname][\'ansible_\' + network_interface][\'ipv4\'][\'address\'] }}:{{nginx_port}}/coreos_production_pxe_image-oem.cpio.gz"', + $deploy_image_filename = '"deployment_image.qcow2"', + $deploy_image = '"{{http_boot_folder}}/{{deploy_image_filename}}"', + $create_image_via_dib = true, + $transform_boot_image = false, + $node_default_network_interface = 'eth0', + $ipv4_subnet_mask = '255.255.255.0', + $ipv4_gateway = '192.168.1.1', + $ipv4_nameserver = '8.8.8.8', + $network_mtu = '1500', + $dhcp_pool_start = '192.168.1.200', + $dhcp_pool_end = '192.168.1.250', + $ipmi_bridging = 'no', +) { + + vcsrepo { $git_dest_repo_folder: + ensure => $ensure, + provider => git, + revision => $revision, + source => $git_source_repo, + } + + file { "${git_dest_repo_folder}/playbooks/inventory/group_vars/all": + ensure => present, + content => template('ironic/group_vars_all.erb'), + require => Vcsrepo[$git_dest_repo_folder], + } + + file { "${git_dest_repo_folder}/baremetal.json": + ensure => present, + content => template('ironic/baremetal.json.erb'), + require => Vcsrepo[$git_dest_repo_folder], + } +} + diff --git a/metadata.json b/metadata.json index 61dc596d..8e9291d1 100644 --- a/metadata.json +++ b/metadata.json @@ -34,6 +34,7 @@ { "name": "puppetlabs/inifile", "version_requirement": ">=1.0.0 <2.0.0" }, { "name": "openstack/keystone", "version_requirement": ">=6.0.0 <7.0.0" }, { "name": "puppetlabs/stdlib", "version_requirement": ">=4.0.0 <5.0.0" }, - { "name": "openstack/openstacklib", "version_requirement": ">=6.0.0 <7.0.0" } + { "name": "openstack/openstacklib", "version_requirement": ">=6.0.0 <7.0.0" }, + { "name": "puppetlabs/vcsrepo", "version_requirement": ">=1.3.0 <2.0.0"} ] } diff --git a/spec/classes/ironic_bifrost_spec.rb b/spec/classes/ironic_bifrost_spec.rb new file mode 100644 index 00000000..6a1f2535 --- /dev/null +++ b/spec/classes/ironic_bifrost_spec.rb @@ -0,0 +1,84 @@ +# Copyright 2015 Hewlett-Packard Development Company, L.P. +# +# Licensed under the Apache License, Version 2.0 (the "License"); you may +# not use this file except in compliance with the License. You may obtain +# a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +# License for the specific language governing permissions and limitations +# under the License. +# +# Unit tests for ironic::bifrost class +# + +require 'spec_helper' + +describe 'ironic::bifrost' do + + let :default_params do + { :git_source_repo => 'https://git.openstack.org/openstack/bifrost', + :revision => master, + :git_dest_repo_folder => '/opt/stack/bifrost', + :ironic_url => '"http://localhost:6385/"', + :network_interface => '"virbr0"', + :testing => false, + :testing_user => 'ubuntu', + :http_boot_folder => '/httpboot', + :nginx_port => 8080, + :ssh_public_key_path => '"{{ ansible_env.HOME }}/.ssh/id_rsa.pub"', + :deploy_kernel => '"{{http_boot_folder}}/coreos_production_pxe.vmlinuz"', + :deploy_ramdisk => '"{{http_boot_folder}}/coreos_production_pxe_image-oem.cpio.gz"', + :deploy_kernel_url => '"http://{{ hostvars[inventory_hostname][\'ansible_\' + network_interface][\'ipv4\'][\'address\'] }}:{{nginx_port}}/coreos_production_pxe.vmlinuz"', + :deploy_ramdisk_url => '"http://{{ hostvars[inventory_hostname][\'ansible_\' + network_interface][\'ipv4\'][\'address\'] }}:{{nginx_port}}/coreos_production_pxe_image-oem.cpio.gz"', + :deploy_image_filename => '"deployment_image.qcow2"', + :deploy_image => '"{{http_boot_folder}}/{{deploy_image_filename}}"', + :create_image_via_dib => true, + :transform_boot_image => false, + :node_default_network_interface => 'eth0', + :ipv4_subnet_mask => '255.255.255.0', + :ipv4_gateway => '192.168.1.1', + :ipv4_nameserver => '8.8.8.8', + :network_mtu => '1500', + :dhcp_pool_start => '192.168.1.200', + :dhcp_pool_end => '192.168.1.250', + :ipmi_bridging => 'no', + } + end + + let :params do + { :mysql_password => 'changeme', + :ironic_db_password => 'changeme', + :baremetal_json_hosts => 'test', + } + end + + it 'should clone with vcsrepo bifrost repo with master branch' do + should contain_vcsrepo('/opt/stack/bifrost').with( + 'ensure' => 'present', + 'provider' => 'git', + 'revision' => 'master', + 'source' => 'https://git.openstack.org/openstack/bifrost', + ) + end + + it 'should contain file group_vars/all' do + should contain_file('/opt/stack/bifrost/playbooks/inventory/group_vars/all').with( + 'ensure' => 'present', + 'require' => 'Vcsrepo[/opt/stack/bifrost]', + 'content' => /ironic_url/, + ) + end + + it 'should contain file baremetal.json' do + should contain_file('/opt/stack/bifrost/baremetal.json').with( + 'ensure' => 'present', + 'require' => 'Vcsrepo[/opt/stack/bifrost]', + 'content' => /test/, + ) + end + +end diff --git a/templates/baremetal.json.erb b/templates/baremetal.json.erb new file mode 100644 index 00000000..9f5bd9c3 --- /dev/null +++ b/templates/baremetal.json.erb @@ -0,0 +1,3 @@ +{ +<%= @baremetal_json_hosts %> +} diff --git a/templates/group_vars_all.erb b/templates/group_vars_all.erb new file mode 100644 index 00000000..0284ca5a --- /dev/null +++ b/templates/group_vars_all.erb @@ -0,0 +1,44 @@ +--- +ironic_url: <%= @ironic_url %> +network_interface: <%= @network_interface %> +# ironic_db_password ironic user password for rabbit +ironic_db_password: <%= @ironic_db_password %> +# mysql_password: mysql root user password +mysql_password: <%= @mysql_password %> +# If testing is true, then the environment is setup for using libvirt +# virtual machines for the hardware instead of real hardware. +# testing: true +# +# Normally this user should be ubuntu, however if cirros is used, +# a user may wish to define a specific user for testing VM +# connectivity during atest sequence +testing: <%= @testing %> +testing_user: <%= @testing_user %> +http_boot_folder: <%= @http_boot_folder %> +nginx_port: <%= @nginx_port %> +ssh_public_key_path: <%= @ssh_public_key_path %> +deploy_kernel: <%= @deploy_kernel %> +deploy_ramdisk: <%= @deploy_ramdisk %> +deploy_kernel_url: <%= @deploy_kernel_url %> +deploy_ramdisk_url: <%= @deploy_ramdisk_url %> +# When using disk image builder based image generation, which is the +# default at this time, the deploy_image_filename must end with .qcow2 +# due to the image creation process. +deploy_image_filename: <%= @deploy_image_filename %> +deploy_image: <%= @deploy_image %> +# Setting to utilize diskimage-builder to create a bootable image. +create_image_via_dib: <%= @create_image_via_dib %> +# Transform boot image is intended for use with the Ubuntu trusty image. It makes the image bootable by installing Grub. +# Setting to prepend a partition image with a boot sector and partition table. +transform_boot_image: <%= @transform_boot_image %> +node_default_network_interface: <%= @node_default_network_interface %> +# ipv4_subnet_mask is intended for the static ipv4 address assignments. +ipv4_subnet_mask: <%= @ipv4_subnet_mask %> +ipv4_gateway: <%= @ipv4_gateway %> +ipv4_nameserver: <%= @ipv4_nameserver %> +network_mtu: <%= @network_mtu %> +dhcp_pool_start: <%= @dhcp_pool_start %> +dhcp_pool_end: <%= @dhcp_pool_end %> +# ipmi_bridging: Default undefined. Valid values: "no", "single", and "dual" +# See http://docs.openstack.org/developer/ironic/_modules/ironic/drivers/modules/ipmitool.html +ipmi_bridging: <%= @ipmi_bridging %>