Skip to content

Commit

Permalink
Merge pull request #2 from lsst-it/IT-4319/connection-hash
Browse files Browse the repository at this point in the history
add nm::connection content param support for hashes
  • Loading branch information
jhoblitt authored Jul 7, 2023
2 parents eee35df + d57cec7 commit 3b504af
Show file tree
Hide file tree
Showing 9 changed files with 277 additions and 33 deletions.
51 changes: 51 additions & 0 deletions examples/connection.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
nm::connection { 'test1':
content => {
'connection' => {
'id' => 'test1',
'type' => 'dummy',
'interface-name' => 'dummy1',
},
'ipv4' => {
'address1' => '10.10.10.10/24',
'method' => 'manual',
},
'ipv6' => {
'method' => 'ignore',
},
},
}

nm::connection { 'test2':
content => {
'connection' => {
'id' => 'test2',
'type' => 'dummy',
'interface-name' => 'dummy2',
},
'ipv4' => {
'address1' => '10.20.20.20/24',
'method' => 'manual',
},
'ipv6' => {
'method' => 'ignore',
},
},
}

nm::connection { 'test3':
# lint:ignore:strict_indent
content => @(NM),
[connection]
id=test3
type=dummy
interface-name=dummy3

[ipv4]
address1=10.30.30.30/24
method=manual

[ipv6]
method=ignore
| NM
# lint:endignore
}
11 changes: 11 additions & 0 deletions examples/connection_absent.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
nm::connection { 'test1':
ensure => 'absent',
}

nm::connection { 'test2':
ensure => 'absent',
}

nm::connection { 'test3':
ensure => 'absent',
}
1 change: 1 addition & 0 deletions examples/nm.pp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
include nm
20 changes: 18 additions & 2 deletions manifests/connection.pp
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,41 @@
# Create a .nmconnection file
#
# @param content
# If a String:
# Verbatim content of .nmconnection "keyfile".
#
# If a Hash:
# Hash of data to serialize to a .nmconnection "keyfile".
#
# See: https://networkmanager.dev/docs/api/latest/nm-settings-keyfile.html
#
# @param ensure
# If connection file should be present or absent.
#
#
define nm::connection (
String[1] $content,
Optional[Variant[String[1], Hash[String, Hash]]] $content = undef,
Enum['present', 'absent'] $ensure = 'present',
) {
include nm

$_real_ensure = $ensure ? {
'absent' => 'absent',
default => 'file',
}

$ini_config = { 'quote_char' => undef }

$_real_content = $content ? {
String => $content,
Hash => extlib::to_ini($content, $ini_config),
default => undef,
}

file { "${nm::conn_dir}/${name}.nmconnection":
ensure => $_real_ensure,
mode => '0600',
content => $content,
content => $_real_content,
notify => Exec['nmcli conn reload'],
}
}
3 changes: 3 additions & 0 deletions manifests/init.pp
Original file line number Diff line number Diff line change
Expand Up @@ -72,5 +72,8 @@
exec { 'nmcli conn reload':
command => '/bin/nmcli conn reload',
refreshonly => true,
timeout => 30,
tries => 3,
try_sleep => 10,
}
}
128 changes: 128 additions & 0 deletions spec/acceptance/connection_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# frozen_string_literal: true

require 'spec_helper_acceptance'

# rubocop:disable RSpec/RepeatedExampleGroupBody
describe 'nm::connection' do
context 'connection' do
include_examples 'the example', 'connection.pp'

it_behaves_like 'an idempotent resource'

describe file('/etc/NetworkManager/system-connections/test1.nmconnection') do
it { is_expected.to be_file }
it { is_expected.to be_owned_by 'root' }
it { is_expected.to be_grouped_into 'root' }
it { is_expected.to be_mode '600' } # serverspec does not like a leading 0

its(:content) do
is_expected.to match <<~CONTENT
# THIS FILE IS CONTROLLED BY PUPPET
[connection]
id=test1
type=dummy
interface-name=dummy1
[ipv4]
address1=10.10.10.10/24
method=manual
[ipv6]
method=ignore
CONTENT
end
end

describe interface('dummy1') do
it { is_expected.to have_ipv4_address('10.10.10.10/24') }
end

describe file('/etc/NetworkManager/system-connections/test2.nmconnection') do
it { is_expected.to be_file }
it { is_expected.to be_owned_by 'root' }
it { is_expected.to be_grouped_into 'root' }
it { is_expected.to be_mode '600' } # serverspec does not like a leading 0

its(:content) do
is_expected.to match <<~CONTENT
# THIS FILE IS CONTROLLED BY PUPPET
[connection]
id=test2
type=dummy
interface-name=dummy2
[ipv4]
address1=10.20.20.20/24
method=manual
[ipv6]
method=ignore
CONTENT
end
end

describe interface('dummy2') do
it { is_expected.to have_ipv4_address('10.20.20.20/24') }
end

describe file('/etc/NetworkManager/system-connections/test3.nmconnection') do
it { is_expected.to be_file }
it { is_expected.to be_owned_by 'root' }
it { is_expected.to be_grouped_into 'root' }
it { is_expected.to be_mode '600' } # serverspec does not like a leading 0

its(:content) do
is_expected.to match <<~CONTENT
[connection]
id=test3
type=dummy
interface-name=dummy3
[ipv4]
address1=10.30.30.30/24
method=manual
[ipv6]
method=ignore
CONTENT
end
end

describe interface('dummy3') do
it { is_expected.to have_ipv4_address('10.30.30.30/24') }
end
end

context 'connection absent' do
include_examples 'the example', 'connection_absent.pp'

it_behaves_like 'an idempotent resource'

describe file('/etc/NetworkManager/system-connections/test1.nmconnection') do
it { is_expected.not_to exist }
end

describe interface('dummy1') do
it { is_expected.not_to exist }
end

describe file('/etc/NetworkManager/system-connections/test2.nmconnection') do
it { is_expected.not_to exist }
end

describe interface('dummy2') do
it { is_expected.not_to exist }
end

describe file('/etc/NetworkManager/system-connections/test3.nmconnection') do
it { is_expected.not_to exist }
end

describe interface('dummy3') do
it { is_expected.not_to exist }
end
end
end
# rubocop:enable RSpec/RepeatedExampleGroupBody
6 changes: 1 addition & 5 deletions spec/acceptance/nm_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@

describe 'nm class' do
context 'without any parameters' do
let(:manifest) do
<<-PP
include nm
PP
end
include_examples 'the example', 'nm.pp'

it_behaves_like 'an idempotent resource'

Expand Down
5 changes: 4 additions & 1 deletion spec/classes/init_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,10 @@
it do
is_expected.to contain_exec('nmcli conn reload').with(
command: '/bin/nmcli conn reload',
refreshonly: true
refreshonly: true,
timeout: 30,
tries: 3,
try_sleep: 10
)
end
end
Expand Down
85 changes: 60 additions & 25 deletions spec/defines/connection_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,84 @@

require 'spec_helper'

shared_examples 'ensure param' do
context 'with ensure =>' do
context 'with absent' do
let(:params) { { content: 'bar', ensure: 'absent' } }

it do
is_expected.to contain_file('/etc/NetworkManager/system-connections/foo.nmconnection').with(
ensure: 'absent'
)
end
end

context 'with present' do
let(:params) { { content: 'bar', ensure: 'present' } }

it do
is_expected.to contain_file('/etc/NetworkManager/system-connections/foo.nmconnection').with(
ensure: 'file'
)
end
end
end
end

describe 'nm::connection' do
on_supported_os.each do |os, facts|
context "on #{os}" do
let(:facts) { facts }
let(:title) { 'foo' }
let(:params) { { content: 'bar' } }

let(:pre_condition) do
<<~PP
include nm
PP
end

it { is_expected.to compile.with_all_deps }
context 'when content is String' do
let(:params) { { content: 'bar' } }

it do
is_expected.to contain_file('/etc/NetworkManager/system-connections/foo.nmconnection').with(
ensure: 'file',
mode: '0600',
content: 'bar'
).that_notifies('Exec[nmcli conn reload]')
end
it { is_expected.to compile.with_all_deps }

context 'with ensure =>' do
context 'with absent' do
let(:params) { { content: 'bar', ensure: 'absent' } }
it do
is_expected.to contain_file('/etc/NetworkManager/system-connections/foo.nmconnection').with(
ensure: 'file',
mode: '0600',
content: 'bar'
).that_notifies('Exec[nmcli conn reload]')
end

it do
is_expected.to contain_file('/etc/NetworkManager/system-connections/foo.nmconnection').with(
ensure: 'absent'
)
end
it_behaves_like 'ensure param'
end

context 'when content is Hash' do
let(:params) do
{
content: {
'bar' => {
'baz' => 'quix',
'quack' => 42,
}
}
}
end

context 'with present' do
let(:params) { { content: 'bar', ensure: 'present' } }
it do
is_expected.to contain_file('/etc/NetworkManager/system-connections/foo.nmconnection').with(
ensure: 'file',
mode: '0600',
content: <<~CONTENT
# THIS FILE IS CONTROLLED BY PUPPET
it do
is_expected.to contain_file('/etc/NetworkManager/system-connections/foo.nmconnection').with(
ensure: 'file'
)
end
[bar]
baz=quix
quack=42
CONTENT
).that_notifies('Exec[nmcli conn reload]')
end

it_behaves_like 'ensure param'
end
end
end
Expand Down

0 comments on commit 3b504af

Please sign in to comment.