This repository has been archived by the owner on Jun 18, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
New helper for fixing user/group properties on Windows and FreeBSD.
This feels like it should be okay for all existing code I think.
- Loading branch information
1 parent
d37378d
commit 6d40cfc
Showing
6 changed files
with
292 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# | ||
# Copyright 2013-2016, Noah Kantrowitz | ||
# | ||
# 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. | ||
# | ||
|
||
require 'chef/mash' | ||
|
||
require 'poise/error' | ||
require 'poise/utils/win32' | ||
|
||
|
||
module Poise | ||
module Helpers | ||
# A resource mixin to intercept properties named `user`, `group`, or `owner`, | ||
# if their default value is `'root'` and make it work on Windows (and | ||
# FreeBSD, AIX). | ||
# | ||
# @since 2.7.0 | ||
# @example | ||
# class MyResource < Chef::Resource | ||
# include Poise::Helpers::Win32User | ||
# attribute(:user, default: 'root') | ||
# attribute(:group, default: 'root') | ||
# end | ||
# @example Avoiding automatic translation | ||
# class MyResource < Chef::Resource | ||
# include Poise::Helpers::Win32User | ||
# attribute(:user, default: lazy { 'root' }) | ||
# attribute(:group, default: lazy { 'root' }) | ||
# end | ||
module Win32User | ||
USER_PROPERTIES = ['user', :user, 'owner', :owner] | ||
GROUP_PROPERTIES = ['group', :group] | ||
|
||
def set_or_return(symbol, arg, options={}) | ||
if options && options[:default] == 'root' | ||
if USER_PROPERTIES.include?(symbol) && node.platform_family?('windows') | ||
options = options.dup | ||
options[:default] = Poise::Utils::Win32.admin_user | ||
elsif GROUP_PROPERTIES.include?(symbol) | ||
options = options.dup | ||
options[:default] = node['root_group'] | ||
end | ||
end | ||
super(symbol, arg, options) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
# | ||
# Copyright 2016, Noah Kantrowitz | ||
# | ||
# 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. | ||
# | ||
|
||
|
||
module Poise | ||
module Utils | ||
module Win32 | ||
extend self | ||
|
||
# Code borrowed from https://github.com/chef-cookbooks/chef-client/blob/master/libraries/helpers.rb | ||
# Used under the terms of the Apache v2 license. | ||
# Copyright 2012-2016, John Dewey | ||
|
||
# Run a WMI query and extracts a property. This assumes Chef has already | ||
# loaded the win32 libraries. | ||
# | ||
# @api private | ||
# @param wmi_property [Symbol] Property to extract. | ||
# @param wmi_query [String] Query to run. | ||
# @return [String] | ||
def wmi_property_from_query(wmi_property, wmi_query) | ||
@wmi = ::WIN32OLE.connect('winmgmts://') | ||
result = @wmi.ExecQuery(wmi_query) | ||
return nil unless result.each.count > 0 | ||
result.each.next.send(wmi_property) | ||
end | ||
|
||
# Find the name of the Administrator user, give or take localization. | ||
# | ||
# @return [String] | ||
def admin_user | ||
wmi_property_from_query(:name, "select * from Win32_UserAccount where sid like 'S-1-5-21-%-500' and LocalAccount=True") | ||
end | ||
|
||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,177 @@ | ||
# | ||
# Copyright 2016, Noah Kantrowitz | ||
# | ||
# 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. | ||
# | ||
|
||
require 'spec_helper' | ||
|
||
describe Poise::Helpers::Win32User do | ||
let(:chefspec_options) { {platform: 'ubuntu', version: '14.04'} } | ||
provider(:poise_test) | ||
before do | ||
allow(Poise::Utils::Win32).to receive(:admin_user).and_return('Administrator') | ||
end | ||
|
||
context 'user property' do | ||
resource(:poise_test) do | ||
include Poise::Helpers::LWRPPolyfill | ||
include described_class | ||
attribute(:user, default: 'root') | ||
end | ||
|
||
context 'with a default' do | ||
recipe do | ||
poise_test 'test' | ||
end | ||
|
||
context 'on Linux' do | ||
it { is_expected.to run_poise_test('test').with(user: 'root') } | ||
end # /context on Linux | ||
|
||
context 'on Windows' do | ||
let(:chefspec_options) { {platform: 'windows', version: '2012r2'} } | ||
it { is_expected.to run_poise_test('test').with(user: 'Administrator') } | ||
end # /context on Windows | ||
end # /context with a default | ||
|
||
context 'with a value' do | ||
recipe do | ||
poise_test 'test' do | ||
user 'other' | ||
end | ||
end | ||
|
||
context 'on Linux' do | ||
it { is_expected.to run_poise_test('test').with(user: 'other') } | ||
end # /context on Linux | ||
|
||
context 'on Windows' do | ||
let(:chefspec_options) { {platform: 'windows', version: '2012r2'} } | ||
it { is_expected.to run_poise_test('test').with(user: 'other') } | ||
end # /context on Windows | ||
end # /context with a value | ||
end # /context user property | ||
|
||
context 'owner property' do | ||
resource(:poise_test) do | ||
include Poise::Helpers::LWRPPolyfill | ||
include described_class | ||
attribute(:owner, default: 'root') | ||
end | ||
|
||
context 'with a default' do | ||
recipe do | ||
poise_test 'test' | ||
end | ||
|
||
context 'on Linux' do | ||
it { is_expected.to run_poise_test('test').with(owner: 'root') } | ||
end # /context on Linux | ||
|
||
context 'on Windows' do | ||
let(:chefspec_options) { {platform: 'windows', version: '2012r2'} } | ||
it { is_expected.to run_poise_test('test').with(owner: 'Administrator') } | ||
end # /context on Windows | ||
end # /context with a default | ||
|
||
context 'with a value' do | ||
recipe do | ||
poise_test 'test' do | ||
owner 'other' | ||
end | ||
end | ||
|
||
context 'on Linux' do | ||
it { is_expected.to run_poise_test('test').with(owner: 'other') } | ||
end # /context on Linux | ||
|
||
context 'on Windows' do | ||
let(:chefspec_options) { {platform: 'windows', version: '2012r2'} } | ||
it { is_expected.to run_poise_test('test').with(owner: 'other') } | ||
end # /context on Windows | ||
end # /context with a value | ||
end # /context owner property | ||
|
||
context 'group property' do | ||
resource(:poise_test) do | ||
include Poise::Helpers::LWRPPolyfill | ||
include described_class | ||
attribute(:group, default: 'root') | ||
end | ||
|
||
context 'with a default' do | ||
recipe do | ||
poise_test 'test' | ||
end | ||
|
||
context 'on Linux' do | ||
it { is_expected.to run_poise_test('test').with(group: 'root') } | ||
end # /context on Linux | ||
|
||
context 'on Windows' do | ||
let(:chefspec_options) { {platform: 'windows', version: '2012r2'} } | ||
# This test is written to be silly because Fauxhai doesn't have | ||
# root_group data for Windows. | ||
it { is_expected.to run_poise_test('test').with(group: chef_run.node['root_group']) } | ||
end # /context on Windows | ||
|
||
context 'on AIX' do | ||
let(:chefspec_options) { {platform: 'aix', version: '6.1'} } | ||
it { is_expected.to run_poise_test('test').with(group: 'system') } | ||
end # /context on AIX | ||
end # /context with a default | ||
|
||
context 'with a value' do | ||
recipe do | ||
poise_test 'test' do | ||
group 'other' | ||
end | ||
end | ||
|
||
context 'on Linux' do | ||
it { is_expected.to run_poise_test('test').with(group: 'other') } | ||
end # /context on Linux | ||
|
||
context 'on Windows' do | ||
let(:chefspec_options) { {platform: 'windows', version: '2012r2'} } | ||
it { is_expected.to run_poise_test('test').with(group: 'other') } | ||
end # /context on Windows | ||
end # /context with a value | ||
end # /context group property | ||
|
||
describe 'interaction with lazy defaults' do | ||
let(:chefspec_options) { {platform: 'windows', version: '2012r2'} } | ||
recipe do | ||
poise_test 'test' | ||
end | ||
|
||
context 'with a non-lazy default' do | ||
resource(:poise_test) do | ||
include Poise::Resource | ||
attribute(:user, default: 'root') | ||
end | ||
|
||
it { is_expected.to run_poise_test('test').with(user: 'Administrator') } | ||
end # /context with a non-lazy default | ||
|
||
context 'with a lazy default' do | ||
resource(:poise_test) do | ||
include Poise::Resource | ||
attribute(:user, default: lazy { 'root' }) | ||
end | ||
|
||
it { is_expected.to run_poise_test('test').with(user: 'root') } | ||
end # /context with a lazy default | ||
end # /describe interaction with lazy defaults | ||
end |
6d40cfc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ping @lamont-granquist @jkeiser for feedbacks. Should make it easier to build resources that JFW on Windows and FreeBSD without a metric ass-ton of
if windows
. I don't know a ton about Windows though, this might be a terrible idea.6d40cfc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hrm...
you might want to look at reviving chef/ohai#698 with your #admin_user code. your code smells a bit better to me, but i still don't know enough about windows to really gauge it...
if the hardcoded System/Administrator thing was dealt with then i could see the utility of
node['root_user']
added there tonode['root_group']
which would give a cross platform way to express what you're trying to do.then i sorta can see a role for monkeypatching that in automagically since most cookbook code hardcodes 'root' and will break on windows but it should probably be opt-in. not positive you're monkeypatching in the right spot, but i haven't dug into FAC/SAC in awhile...