Skip to content

Commit

Permalink
Release/1.9 (#73)
Browse files Browse the repository at this point in the history
* Add documentation detailing new certificate resource changes incorporating the -T option

* modify security library and certificate resource to accomodate -T option

* Testing for new and improved certificate resource

* Fix Chef Spec tests

* bump version to 1.9.0

* hotfix for plist encoding type utf-8

* move plutil_format_map to libraries

* using Chef::Application.fatal to enforce encoding types

* add one second after each systemsetup call

* Add support for more hypervisors in keep_awake

- Leverage the node['virtualization']['systems'] ohai attribute to
determine whether we are a guest or a host
- Add appropriate chefspec tests

* Add another context for empty virtualization hash

* bump to 1.8.1

* ensure xcode-install gem is in Chef embedded even if ChefDK is present

* adjust implementation of running_in_a_vm?

* fix rspec shared context

* re-arrange chefspec keep_awake unit tests
  • Loading branch information
americanhanko authored Mar 21, 2018
1 parent df5457d commit 0db7830
Show file tree
Hide file tree
Showing 14 changed files with 178 additions and 31 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ Resources
---------

- [ARD (Apple Remote Desktop)](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_ard.md)
- [Certificate](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_certificate.md)
- [Certificate (security)](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_certificate.md)
- [Machine Name](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_machine_name.md)
- [Plist](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_plist.md)
- [Spotlight (mdutil)](https://github.com/Microsoft/macos-cookbook/blob/master/documentation/resource_spotlight.md)
Expand Down
10 changes: 10 additions & 0 deletions documentation/resource_certificate.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ certificate 'cert name' do
certfile String # certificate in .p12(PFX) or .cer(SSl certificate file) format
cert_passwd String # password for PFX format certificate file
keychain String # keychain to install certificate to
apps Array # list of apps that may access the imported key
end
```

Expand Down Expand Up @@ -69,4 +70,13 @@ certificate 'cert name' do
certfile '/User/edward/Documents/cert.p12'
keychain '/User/edward/Library/Keychains/florida.keychain'
end
```

**Install PFX format certificate to default keychain, accessible by certain app**
```ruby
certificate 'cert name' do
certfile '/User/edward/Documents/cert.p12'
cert_passwd 'teach'
apps ['/Applications/Maps.app', '/Applications/Time Machine.app']
end
```
12 changes: 10 additions & 2 deletions libraries/plist.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ def setting_from_plist(entry, path)
{ key_type: defaults_read_type_output.split.last, key_value: defaults_read_output.strip }
end

def plutil_format_map
{ 'us-ascii' => 'xml1',
'text/xml' => 'xml1',
'utf-8' => 'xml1',
'binary' => 'binary1' }
end

private

def defaults_executable
Expand All @@ -92,5 +99,6 @@ def plistbuddy_executable
end
end

Chef::Recipe.include(MacOS::PlistHelpers)
Chef::Resource.include(MacOS::PlistHelpers)
Chef::Recipe.include MacOS::PlistHelpers
Chef::Resource.include MacOS::PlistHelpers
Chef::DSL::Recipe.include MacOS::MachineName
20 changes: 16 additions & 4 deletions libraries/security_cmd.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,28 @@ def add_certificates
@keychain == '' ? [@security_cmd, 'add-certificates', @cert] : [@security_cmd, 'add-certificates', @cert, '-k', @keychain]
end

def import(cert_passwd)
@keychain == '' ? [@security_cmd, 'import', @cert, '-P', cert_passwd] : [@security_cmd, 'import', @cert, '-P', cert_passwd, '-k', @keychain]
def import(cert_passwd, apps)
app_array = []

apps.each do |app|
app_array.push('-T')
app_array.push(app)
end
@keychain == '' ? [@security_cmd, 'import', @cert, '-P', cert_passwd, *app_array] : [@security_cmd, 'import', @cert, '-P', cert_passwd, '-k', @keychain, *app_array]
end

def install_certificate(cert_passwd)
def install_certificate(cert_passwd, apps)
valid_pkcs12 = ['.p12', '.pfx']
valid_certs = ['.der', '.crt', '.cer']

apps.each do |app|
unless app.is_a? String
Chef::Exception.fatal("Invalid application: #{@app}.")
end
end

if valid_pkcs12.any? { |extension| ::File.extname(@cert).match? extension }
import(cert_passwd)
import(cert_passwd, apps)
elsif valid_certs.any? { |extension| ::File.extname(@cert).match? extension }
add_certificates
else
Expand Down
3 changes: 2 additions & 1 deletion libraries/systemsetup.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
module MacOS
module SystemSetup
def running_in_a_vm?
Chef.node['hardware']['machine_model'].match?(/Parallels/) # TODO: cover more hypervisors
virtualization_systems = Chef.node['virtualization']['systems']
virtualization_systems.empty? || virtualization_systems.values.include?('guest') ? true : false
end

def power_button_model?
Expand Down
2 changes: 1 addition & 1 deletion metadata.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
description 'Resources for configuring and provisioning macOS'
long_description IO.read(File.join(File.dirname(__FILE__), 'README.md'))
chef_version '~> 13.0' if respond_to?(:chef_version)
version '1.8.2'
version '1.9.0'

source_url 'https://github.com/Microsoft/macos-cookbook'
issues_url 'https://github.com/Microsoft/macos-cookbook/issues'
Expand Down
3 changes: 2 additions & 1 deletion resources/certificate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
property :certfile, String
property :cert_password, String
property :keychain, String
property :apps, Array

action_class do
def keychain
Expand All @@ -18,6 +19,6 @@ def keychain
end

execute 'install-certificate' do
command [*cert.install_certificate(new_resource.cert_password)]
command [*cert.install_certificate(new_resource.cert_password, new_resource.apps)]
end
end
13 changes: 4 additions & 9 deletions resources/plist.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
property :path, String, name_property: true, desired_state: true
property :entry, String, desired_state: true
property :value, [TrueClass, FalseClass, String, Integer, Float], desired_state: true
property :encoding, String, desired_state: true, default: 'binary', equal_to: ['text/xml', 'binary', 'us-ascii']
property :encoding, String, desired_state: true, default: 'binary'

load_current_value do |desired|
current_value_does_not_exist! unless ::File.exist? desired.path
Expand Down Expand Up @@ -52,17 +52,12 @@

converge_if_changed :encoding do
converge_by 'change format' do
Chef::Application.fatal!(
"Option encoding must be equal to one of: #{plutil_format_map.keys}! You passed \"#{new_resource.encoding}\"."
) unless plutil_format_map.keys.include? new_resource.encoding
execute ['/usr/bin/plutil', '-convert', plutil_format_map[new_resource.encoding], new_resource.path] do
action :run
end
end
end
end

action_class do
def plutil_format_map
{ 'us-ascii' => 'xml1',
'text/xml' => 'xml1',
'binary' => 'binary1' }
end
end
5 changes: 5 additions & 0 deletions resources/system_preference.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,11 @@
converge_by "set #{new_resource.preference} to #{new_resource.setting}" do
set_pref = ['-set', new_resource.preference.to_s].join('')
execute ['/usr/sbin/systemsetup', set_pref, new_resource.setting]
ruby_block 'sleep one second' do
block do
sleep 1
end
end
end
end
end
2 changes: 1 addition & 1 deletion resources/xcode.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

action :setup do
chef_gem 'xcode-install' do
options('--no-document')
options('--no-document --no-user-install')
end

CREDENTIALS_DATA_BAG = data_bag_item(:credentials, :apple_id)
Expand Down
14 changes: 10 additions & 4 deletions spec/unit/libraries/security_cmd_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,19 @@

context 'importing a certificate (.p12)' do
it 'imports a specified .p12 certificate file' do
expect(p12_cert.import('password')).to eq ['/usr/bin/security', 'import', '/Users/vagrant/Test.p12', '-P', 'password']
expect(p12_cert.import('password', [])).to eq ['/usr/bin/security', 'import', '/Users/vagrant/Test.p12', '-P', 'password']
end
end

context 'importing a certificate (.p12)' do
it 'imports a specified .p12 certificate file to a specified keychain' do
expect(p12_cert_kc.import('password')).to eq ['/usr/bin/security', 'import', '/Users/vagrant/Test.p12', '-P', 'password', '-k', 'test.keychain']
expect(p12_cert_kc.import('password', [])).to eq ['/usr/bin/security', 'import', '/Users/vagrant/Test.p12', '-P', 'password', '-k', 'test.keychain']
end
end

context 'importing a certificate (.p12) accessible by Mail and App Store ' do
it 'imports a specified .p12 certificate file to a specified keychain' do
expect(p12_cert_kc.import('password', ['/Applications/Mail.app', '/Applications/App Store.app'])).to eq ['/usr/bin/security', 'import', '/Users/vagrant/Test.p12', '-P', 'password', '-k', 'test.keychain', '-T', '/Applications/Mail.app', '-T', '/Applications/App Store.app']
end
end

Expand All @@ -63,13 +69,13 @@

context 'installing a certificate (.p12)' do
it 'installs a specified .p12 certificate file' do
expect(p12_cert.install_certificate('password')).to eq ['/usr/bin/security', 'import', '/Users/vagrant/Test.p12', '-P', 'password']
expect(p12_cert.install_certificate('password', [])).to eq ['/usr/bin/security', 'import', '/Users/vagrant/Test.p12', '-P', 'password']
end
end

context 'installing a certificate (.cer)' do
it 'adds a specified .cer certificate file' do
expect(cer_cert.install_certificate('password')).to eq ['/usr/bin/security', 'add-certificates', '/Users/vagrant/Test.cer']
expect(cer_cert.install_certificate('password', [])).to eq ['/usr/bin/security', 'add-certificates', '/Users/vagrant/Test.cer']
end
end
end
120 changes: 114 additions & 6 deletions spec/unit/recipes/keep_awake_spec.rb
Original file line number Diff line number Diff line change
@@ -1,13 +1,121 @@
require 'spec_helper'

describe 'macos::keep_awake' do
context 'When all attributes are default, on macOS High Sierra 10.13' do
let(:chef_run) { ChefSpec::SoloRunner.new.converge(described_recipe) }
include MacOS::SystemSetup

shared_context 'when running on bare metal' do
shared_examples 'setting metal-specific power preferences' do
before(:each) do
allow_any_instance_of(Chef::Resource).to receive(:power_button_model?).and_return(true)
chef_run.node.normal['virtualization']['systems'] = { 'vbox' => 'host', 'parallels' => 'host' }
stub_command('which git').and_return('/usr/bin/git')
end

it 'returns false' do
expect(running_in_a_vm?).to be false
end

it 'sets wake on lan' do
chef_run.converge(described_recipe)
expect(chef_run).to set_system_preference('wake the computer when accessed using a network connection')
end

it 'disables power button sleep' do
chef_run.converge(described_recipe)
expect(chef_run).to set_system_preference('pressing power button does not sleep computer')
end

it 'sets restart after a power failure' do
chef_run.converge(described_recipe)
expect(chef_run).to set_system_preference('restart after a power failure')
end

it 'converges successfully on bare metal' do
expect { chef_run }.to_not raise_error
end
end
end

shared_context 'running in a parallels virtual machine' do
before(:each) do
allow_any_instance_of(Chef::Resource).to receive(:power_button_model?).and_return(false)
chef_run.node.normal['virtualization']['systems'] = { 'parallels' => 'guest' }
stub_command('which git').and_return('/usr/bin/git')
end

shared_examples 'not setting metal-specific power prefs' do
it 'confirms we are in a vm' do
expect(running_in_a_vm?).to be true
end

it 'does not set wake on lan' do
chef_run.converge(described_recipe)
expect(chef_run).to_not set_system_preference('wake the computer when accessed using a network connection')
end

it 'skips disabling power button sleep' do
chef_run.converge(described_recipe)
expect(chef_run).to_not set_system_preference('pressing power button does not sleep computer')
end

it 'does not set restart after a power failure' do
chef_run.converge(described_recipe)
expect(chef_run).to_not set_system_preference('restart after a power failure')
end

it 'converges successfully' do
allow_any_instance_of(Chef::Resource).to receive(:running_in_a_vm?).and_return(false)
allow_any_instance_of(Chef::Resource).to receive(:power_button_model?).and_return(false)
it 'converges successfully in a vm' do
expect { chef_run }.to_not raise_error
end
end
end

shared_context 'running in an undetermined virtualization system' do
before(:each) do
allow_any_instance_of(Chef::Resource).to receive(:power_button_model?).and_return(false)
chef_run.node.override['virtualization']['systems'] = {}
stub_command('which git').and_return('/usr/bin/git')
end

shared_examples 'not setting metal-specific power prefs' do
it 'assumes we are in a vm' do
expect(running_in_a_vm?).to be true
end

it 'does not set wake on lan' do
chef_run.converge(described_recipe)
expect(chef_run).to_not set_system_preference('wake the computer when accessed using a network connection')
end

it 'skips disabling power button sleep' do
chef_run.converge(described_recipe)
expect(chef_run).to_not set_system_preference('pressing power button does not sleep computer')
end

it 'does not set restart after a power failure' do
chef_run.converge(described_recipe)
expect(chef_run).to_not set_system_preference('restart after a power failure')
end

it 'converges successfully in a vm' do
expect { chef_run }.to_not raise_error
end
end
end

describe 'macos::keep_awake' do
let(:chef_run) { ChefSpec::SoloRunner.new }

describe 'keep_awake in a parallels vm' do
include_context 'running in a parallels virtual machine'
it_behaves_like 'not setting metal-specific power prefs'
end

describe 'keep_awake in an undetermined virtualization system' do
include_context 'running in an undetermined virtualization system'
it_behaves_like 'not setting metal-specific power prefs'
end

describe 'keep_awake on bare metal' do
include_context 'when running on bare metal'
it_behaves_like 'setting metal-specific power preferences'
end
end
1 change: 1 addition & 0 deletions test/cookbooks/macos_test/recipes/certificate.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@
certfile '/Users/vagrant/Test.p12'
cert_password 'test'
keychain '/Users/vagrant/Library/Keychains/login.keychain'
apps ['/Applications/Mail.app', '/Applications/App Store.app']
action :install
end
2 changes: 1 addition & 1 deletion test/smoke/default/new_users_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
its('groups') { should_not include 'admin' }
end

describe groups.where { name == 'admin'} do
describe groups.where { name == 'admin' } do
it { should exist }
its('gids') { should include 80 }
end
Expand Down

0 comments on commit 0db7830

Please sign in to comment.