Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Uncouple from the puppet_litmus gem #260

Merged
merged 2 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 12 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ $ cat ~/.fog
##### Setting up a new machine

```ruby
$ bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::abs --targets localhost action=provision platform=ubuntu-1604-x86_64 inventory=/Users/tp/workspace/git/provision/inventory.yaml
$ bundle exec bolt task run provision::abs --targets localhost action=provision platform=ubuntu-1604-x86_64

Started on localhost...
Finished on localhost:
Expand All @@ -118,7 +118,7 @@ Ran on 1 node in 1.44 seconds
##### Tearing down a finished machine

```ruby
$ bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::abs --targets localhost action=tear_down inventory=/Users/tp/workspace/git/provision/inventory.yaml node_name=yh6f4djvz7o3te6.delivery.puppetlabs.net
$ bundle exec bolt task run provision::abs --targets localhost action=tear_down node_name=yh6f4djvz7o3te6.delivery.puppetlabs.net

Started on localhost...
Finished on localhost:
Expand All @@ -139,7 +139,7 @@ Containers by default will be managed in the current [docker context](https://do
#### Provision

```ruby
$ bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::docker --targets localhost action=provision platform=ubuntu:14.04 inventory=/Users/tp/workspace/git/provision/inventory.yaml
$ bundle exec bolt task run provision::docker --targets localhost action=provision platform=ubuntu:14.04

Started on localhost...
Finished on localhost:
Expand All @@ -166,13 +166,13 @@ These defaults can be overriden by passing the flags with different values i.e.
```

```ruby
bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::docker --targets localhost action=provision platform=ubuntu:14.04 inventory=/Users/tp/workspace/git/provision/inventory.yaml vars='{ "docker_run_opts": ["-p 8086:8086", "-p 3000:3000"]}'
bundle exec bolt task run provision::docker --targets localhost action=provision platform=ubuntu:14.04 vars='{ "docker_run_opts": ["-p 8086:8086", "-p 3000:3000"]}'
```

#### Tear down

```ruby
$ bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::docker --targets localhost action=tear_down inventory=/Users/tp/workspace/git/provision/inventory.yaml node_name=localhost:2222
$ bundle exec bolt task run provision::docker --targets localhost action=tear_down node_name=localhost:2222

Started on localhost...
Finished on localhost:
Expand All @@ -197,7 +197,7 @@ Tested with vagrant images:
provision

```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/inventory.yaml
$ bundle exec bolt task run provision::vagrant --targets localhost action=provision platform=ubuntu/xenial64

Started on localhost...
Finished on localhost:
Expand All @@ -212,7 +212,7 @@ 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'
$ bundle exec bolt 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
Expand All @@ -223,7 +223,7 @@ This leads to errors when anything tries to execute `puppet` commands on the tes
To add the Puppet agent binary path to the *secure_path* please run the `provision::fix_secure_path` Bolt task:

```ruby
$ bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::fix_secure_path path=/opt/puppetlabs/bin -i inventory.yaml -t ssh_nodes
$ bundle exec bolt task run provision::fix_secure_path path=/opt/puppetlabs/bin -i inventory.yaml -t ssh_nodes

Started on 127.0.0.1:2222...
Finished on 127.0.0.1:2222:
Expand All @@ -235,7 +235,7 @@ Ran on 1 target in 0.84 sec
tear_down

```ruby
$ bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::vagrant --targets localhost action=tear_down inventory=/Users/tp/workspace/git/provision/inventory.yaml node_name=127.0.0.1:2222
$ bundle exec bolt task run provision::vagrant --targets localhost action=tear_down node_name=127.0.0.1:2222

Started on localhost...
Finished on localhost:
Expand Down Expand Up @@ -290,7 +290,7 @@ 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/inventory.yaml vars='role: puppetserver'
bundle exec bolt task run provision::provision_service --targets localhost action=provision platform=centos-7-v20200813 inventory=/Users/tp/workspace/git/provision/inventory.yaml vars='role: puppetserver'
```

Or using Litmus:
Expand Down Expand Up @@ -326,7 +326,7 @@ provision

```powershell
PS> $env:LITMUS_HYPERV_VSWITCH = 'internal_nat'
PS> bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::vagrant --targets localhost action=provision platform=centos/7 inventory=/Users/tp/workspace/git/provision/inventory.yaml hyperv_smb_username=tp hyperv_smb_password=notMyrealPassword
PS> bundle exec bolt task run provision::vagrant --targets localhost action=provision platform=centos/7 hyperv_smb_username=tp hyperv_smb_password=notMyrealPassword
Started on localhost...
Finished on localhost:
Expand Down Expand Up @@ -359,7 +359,7 @@ Testing/development/debugging it is better to use ruby directly, you will need t
Testing using bolt, the second step

```ruby
bundle exec bolt --modulepath /Users/tp/workspace/git/ task run provision::docker --targets localhost action=provision platform=ubuntu:14.04 inventory=/Users/tp/workspace/git/provision/inventory.yaml
bundle exec bolt task run provision::docker --targets localhost action=provision platform=ubuntu:14.04
```

## License
Expand Down
20 changes: 5 additions & 15 deletions lib/docker_helper.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# frozen_string_literal: true

require 'json'
require 'puppet_litmus'

def docker_exec(container, command)
run_local_command("docker exec #{container} #{command}")
def docker_exec(container_id, command)
run_local_command("docker exec #{container_id} #{command}")
end

def docker_image_os_release_facts(image)
Expand Down Expand Up @@ -34,18 +33,9 @@ def docker_image_os_release_facts(image)
os_release_facts
end

def docker_tear_down(node_name, inventory_location)
extend PuppetLitmus::InventoryManipulation
inventory_full_path = File.join(inventory_location, '/spec/fixtures/litmus_inventory.yaml')
raise "Unable to find '#{inventory_full_path}'" unless File.file?(inventory_full_path)

inventory_hash = inventory_hash_from_inventory_file(inventory_full_path)
node_facts = facts_from_node(inventory_hash, node_name)
remove_docker = "docker rm -f #{node_facts['container_id']}"
run_local_command(remove_docker)
remove_node(inventory_hash, node_name)
puts "Removed #{node_name}"
File.open(inventory_full_path, 'w') { |f| f.write inventory_hash.to_yaml }
def docker_tear_down(container_id)
run_local_command("docker rm -f #{container_id}")
puts "Removed #{container_id}"
{ status: 'ok' }
end

Expand Down
119 changes: 119 additions & 0 deletions lib/inventory_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# frozen_string_literal: true

require 'yaml'
require 'delegate'
require 'json'

# simple bolt inventory manipulator
class InventoryHelper < SimpleDelegator
def initialize(location)
@location = location
super(refresh)
end

# Load inventory from location in YAML format
# or generate a default structure
#
# @return [Hash]
def refresh
x = JSON.parse(YAML.load_file(@location).to_json) if File.file?(@location)
{ 'version' => 2, 'groups' => [] }.merge(x || {})
end

# Save inventory to location in yaml format
def save
File.open(@location, 'wb+') { |f| f.write(to_yaml) }
self
end

# Adds a node to a group specified, if group_name exists in inventory hash.
#
# @param node [Hash] node to add to the group
# @param group [String] group of nodes to limit the search for the node_name in
# @return [Hash] inventory_hash with node added to group if group_name exists in inventory hash.
def add(node, group)
# stringify keys
node = JSON.parse(node.to_json)
# check if group exists
if self['groups'].any? { |g| g['name'] == group }
self['groups'].each do |g|
g['targets'].push(node) if g['name'] == group
end
else
# add new group
self['groups'].push({ 'name' => group, 'targets' => [node] })
end

self
end

# Lookup a node
#
# @param either [String] uri or name of node to find
# @param uri [String] uri of node to find
# @param name [String] name of node to find
# @param group [String] limit search to group
# @return [Hash] inventory target
def lookup(either = nil, uri: nil, name: nil, group: nil)
value = either || uri || name

keys = []
keys << 'uri' if uri || either
keys << 'name' if name || either

self['groups'].each do |g|
next unless (group && group == g['name']) || group.nil?
g['targets'].each do |t|
return t if keys.include? t.key(value)
end
end

raise "Failed to lookup target #{value}"
end

# Remove node
#
# @param node [Hash]
# @return [Hash] inventory_hash with node of node_name removed.
def remove(node)
# stringify keys
node = JSON.parse(node.to_json)
self['groups'].map! do |g|
g['targets'].reject! { |target| target == node }
g
end

self
end

class << self
attr_accessor :instances

def open(location = nil)
# Inventory location is an optional task parameter.
location = location.nil? ? Dir.pwd : location
location = if File.directory?(location)
# DEPRECATED: puppet_litmus <= 1.4.0 support
if Gem.loaded_specs['puppet_litmus'] && Gem.loaded_specs['puppet_litmus'].version <= Gem::Version.new('1.4.0')
File.join(location, 'spec', 'fixtures', 'litmus_inventory.yaml')
else
File.join(location, 'inventory.yaml')
end
else
location
end

raise "directory for storing inventory does not exist: #{location}" unless File.exist?(File.dirname(location))

@instances ||= {}
@instances[location] = new(location) unless @instances.key? location
@instances[location]
end
end

attr_reader :location

protected

attr_writer :location
end
32 changes: 0 additions & 32 deletions lib/task_helper.rb
Original file line number Diff line number Diff line change
@@ -1,37 +1,5 @@
# frozen_string_literal: true

def sanitise_inventory_location(location)
# Inventory location is an optional task parameter.
location = location.nil? ? Dir.pwd : location
# If not specified use the current directory + inventory.yaml
if File.exist?(location) && File.directory?(location)
# DEPRECATED: puppet_litmus <= 1.4.0 support
if Gem.loaded_specs['puppet_litmus'].version <= Gem::Version.new('1.4.0')
File.join(location, 'spec', 'fixtures', 'litmus_inventory.yaml')
else
File.join(location, 'inventory.yaml')
end
else
location
end
end

def get_inventory_hash(inventory_full_path)
if File.file?(inventory_full_path)
inventory_hash_from_inventory_file(inventory_full_path)
else
{
'version' => 2,
'groups' => [
{ 'name' => 'docker_nodes', 'targets' => [] },
{ 'name' => 'lxd_nodes', 'targets' => [] },
{ 'name' => 'ssh_nodes', 'targets' => [] },
{ 'name' => 'winrm_nodes', 'targets' => [] },
]
}
end
end

def run_local_command(command, dir = Dir.pwd)
require 'open3'
stdout, stderr, status = Open3.capture3(command, chdir: dir)
Expand Down
19 changes: 19 additions & 0 deletions spec/spec_helper_local.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
require 'fileutils'

RSpec.configure do |rspec|
rspec.expect_with :rspec do |c|
c.max_formatted_output_length = nil
end
end

RSpec.shared_context('with tmpdir') do
let(:tmpdir) { @tmpdir } # rubocop:disable RSpec/InstanceVariable

around(:each) do |example|
Dir.mktmpdir('rspec-provision_test') do |t|
FileUtils.mkdir_p(File.join(t, 'spec', 'fixtures'))
@tmpdir = t
example.run
end
end
end
11 changes: 0 additions & 11 deletions spec/tasks/abs_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,6 @@
require_relative '../../tasks/abs'
require 'yaml'

RSpec.shared_context('with tmpdir') do
let(:tmpdir) { @tmpdir } # rubocop:disable RSpec/InstanceVariable

around(:each) do |example|
Dir.mktmpdir('rspec-provision_test') do |t|
@tmpdir = t
example.run
end
end
end

describe 'provision::abs' do
let(:abs) { ABSProvision.new }
let(:inventory_dir) { "#{tmpdir}/spec/fixtures" }
Expand Down Expand Up @@ -131,7 +120,7 @@
expect(abs.task(**params)).to eq({ status: 'ok', nodes: 1 })
end

it 'raises an error if abs returns error response'

Check warning on line 123 in spec/tasks/abs_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

provision::abs when provisioning raises an error if abs returns error response Skipped: Not yet implemented

Check warning on line 123 in spec/tasks/abs_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

provision::abs when provisioning raises an error if abs returns error response Skipped: Not yet implemented
end

context 'when tearing down' do
Expand Down Expand Up @@ -179,6 +168,6 @@
end
end

it 'raises an error if abs returns error response'

Check warning on line 171 in spec/tasks/abs_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 7.24, Ruby Ver: 2.7)

provision::abs when tearing down raises an error if abs returns error response Skipped: Not yet implemented

Check warning on line 171 in spec/tasks/abs_spec.rb

View workflow job for this annotation

GitHub Actions / Spec / Spec tests (Puppet: ~> 8.0, Ruby Ver: 3.2)

provision::abs when tearing down raises an error if abs returns error response Skipped: Not yet implemented
end
end
Loading
Loading