From f0390dda56f761d6b7b9c6763cff09191cc5d8f9 Mon Sep 17 00:00:00 2001 From: jordanbreen28 Date: Wed, 15 May 2024 14:20:42 +0100 Subject: [PATCH 1/4] (CAT-372) - Add var support for vagrant provisioner To use multi-node provisioning locally with vagrant we need to be able to assign arbitrary tags to the nodes we deploy. Other provisioners do this with a parameter called vars. This commit introduces support for this, and essentially copies what is already present in the other bolt tasks in this module. --- tasks/vagrant.json | 4 ++++ tasks/vagrant.rb | 10 ++++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/tasks/vagrant.json b/tasks/vagrant.json index 906ed76d..ceb2d6ae 100644 --- a/tasks/vagrant.json +++ b/tasks/vagrant.json @@ -58,6 +58,10 @@ "password": { "description": "Password to use for Vagrant boxes without the default Vagrant insecure key", "type": "Optional[String[1]]" + }, + "vars": { + "description": "YAML string of key/value pairs to add to the inventory vars section", + "type": "Optional[String[1]]" } }, "files": [ diff --git a/tasks/vagrant.rb b/tasks/vagrant.rb index 07c81e67..bf16aceb 100755 --- a/tasks/vagrant.rb +++ b/tasks/vagrant.rb @@ -115,7 +115,7 @@ def configure_remoting(platform, remoting_config_path, password) remoting_config end -def provision(platform, inventory_location, enable_synced_folder, provider, cpus, memory, hyperv_vswitch, hyperv_smb_username, hyperv_smb_password, box_url, password) +def provision(platform, inventory_location, enable_synced_folder, provider, cpus, memory, hyperv_vswitch, hyperv_smb_username, hyperv_smb_password, box_url, password, vars) if platform_is_windows?(platform) && !supports_windows_platform? raise "To provision a Windows VM with this task you must have vagrant 2.2.0 or later installed; vagrant seems to be installed at v#{vagrant_version}" end @@ -186,6 +186,11 @@ def provision(platform, inventory_location, enable_synced_folder, provider, cpus } group_name = 'winrm_nodes' end + # Add the vars hash to the node if they are passed exists + unless vars.nil? + var_hash = YAML.safe_load(vars) + node['vars'] = var_hash + end add_node_to_group(inventory_hash, node, group_name) File.open(inventory_full_path, 'w') { |f| f.write inventory_hash.to_yaml } { status: 'ok', node_name: node_name, node: node } @@ -212,6 +217,7 @@ def tear_down(node_name, inventory_location) platform = params['platform'] action = params['action'] node_name = params['node_name'] +vars = params['vars'] inventory_location = sanitise_inventory_location(params['inventory']) enable_synced_folder = params['enable_synced_folder'].nil? ? ENV.fetch('VAGRANT_ENABLE_SYNCED_FOLDER', nil) : params['enable_synced_folder'] enable_synced_folder = enable_synced_folder.casecmp('true').zero? if enable_synced_folder.is_a?(String) @@ -238,7 +244,7 @@ def tear_down(node_name, inventory_location) end begin - result = provision(platform, inventory_location, enable_synced_folder, provider, cpus, memory, hyperv_vswitch, hyperv_smb_username, hyperv_smb_password, box_url, password) if action == 'provision' + result = provision(platform, inventory_location, enable_synced_folder, provider, cpus, memory, hyperv_vswitch, hyperv_smb_username, hyperv_smb_password, box_url, password, vars) if action == 'provision' result = tear_down(node_name, inventory_location) if action == 'tear_down' puts result.to_json exit 0 From 65e6de1ea8ff33cb33fc40a0bb6d22da6d8d54dd Mon Sep 17 00:00:00 2001 From: jordanbreen28 Date: Wed, 15 May 2024 14:23:35 +0100 Subject: [PATCH 2/4] (CAT-372) - Add readme examples of vars --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3eaa71e7..993be9b8 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,12 @@ Successful on 1 node: localhost Ran on 1 node in 51.98 seconds ``` +For multi-node provisioning, you can assign arbitrary tags to the nodes you deploy, by passing an optional YAML-string 'vars' to the bolt task. In the example below we are assigning the role of `k8s-controller` to the provisioned node. + +```ruby +$ bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::vagrant --targets localhost action=provision platform=ubuntu/xenial64 inventory=/Users/tp/workspace/git/provision vars='role: k8s-controller' +``` + sudo secure_path fix As some Vagrant boxes do not allow ssh root logins, the **vagrant** user is used to login and *sudo* is used to execute privileged commands as root user. @@ -284,13 +290,13 @@ In the provision step you can invoke bundle exec rake 'litmus:provision_list[tes Manual invocation of the provision service task from a workflow can be done using: ```ruby -bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::provision_service --targets localhost action=provision platform=centos-7-v20200813 inventory=/Users/tp/workspace/git/provision +bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::provision_service --targets localhost action=provision platform=centos-7-v20200813 inventory=/Users/tp/workspace/git/provision vars='role: puppetserver' ``` Or using Litmus: ```ruby -bundle exec rake 'litmus:provision[provision_service, centos-7-v20200813]' +bundle exec rake 'litmus:provision[provision_service, centos-7-v20200813, role: puppetserver]' ``` #### Synced Folders From 2b89d5a7ab3af4bd8d00ee65b66006033e9a4820 Mon Sep 17 00:00:00 2001 From: jordanbreen28 Date: Wed, 15 May 2024 14:34:27 +0100 Subject: [PATCH 3/4] (maint) - Fix Layout/LineLength --- tasks/vagrant.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tasks/vagrant.rb b/tasks/vagrant.rb index bf16aceb..9594a863 100755 --- a/tasks/vagrant.rb +++ b/tasks/vagrant.rb @@ -244,7 +244,10 @@ def tear_down(node_name, inventory_location) end begin - result = provision(platform, inventory_location, enable_synced_folder, provider, cpus, memory, hyperv_vswitch, hyperv_smb_username, hyperv_smb_password, box_url, password, vars) if action == 'provision' + if action == 'provision' + result = provision(platform, inventory_location, enable_synced_folder, provider, cpus, memory, hyperv_vswitch, hyperv_smb_username, hyperv_smb_password, box_url, password, +vars) + end result = tear_down(node_name, inventory_location) if action == 'tear_down' puts result.to_json exit 0 From 3fc3502001425b5367dff24ebdd430558335d041 Mon Sep 17 00:00:00 2001 From: jordanbreen28 Date: Wed, 15 May 2024 16:57:13 +0100 Subject: [PATCH 4/4] (CAT-372) - Add tests for vagrant provision --- spec/tasks/vagrant_spec.rb | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 spec/tasks/vagrant_spec.rb diff --git a/spec/tasks/vagrant_spec.rb b/spec/tasks/vagrant_spec.rb new file mode 100644 index 00000000..5972ed5b --- /dev/null +++ b/spec/tasks/vagrant_spec.rb @@ -0,0 +1,34 @@ +require 'json' +require 'rspec' +require 'spec_helper' +require 'net/ssh' + +describe 'vagrant' do + let(:provider) { 'virtualbox' } + let(:platform) { 'generic/debian10' } + + before(:each) do + # Stub $stdin.read to return a predefined JSON string + allow($stdin).to receive(:read).and_return({ + platform: platform, + action: 'provision', + vars: 'role: worker1', + inventory: Dir.pwd.to_s, + enable_synced_folder: 'true', + provider: provider, + hyperv_vswitch: 'hyperv_vswitch', + hyperv_smb_username: 'hyperv_smb_username' + }.to_json) + allow(Open3).to receive(:capture3).with(%r{vagrant up --provider #{provider}}, any_args).and_return(['', '', 0]).once + allow(File).to receive(:read).with(%r{#{Dir.pwd}/.vagrant}).and_return('some_unique_id') + allow(Open3).to receive(:capture3).with(%r{vagrant ssh-config}, any_args).and_return(['', '', 0]).once + allow(Net::SSH).to receive(:start).and_return(true) + require_relative '../../tasks/vagrant' + end + + it 'provisions a new vagrant box when action is provision' do + expect { vagrant }.to output(%r{"status":"ok"}).to_stdout + expect { vagrant }.to output(%r{"platform":"generic/debian10"}).to_stdout + expect { vagrant }.to output(%r{"role":"worker1"}).to_stdout + end +end