Initial Chef repository
This commit is contained in:
119
cookbooks/sudo/CHANGELOG.md
Normal file
119
cookbooks/sudo/CHANGELOG.md
Normal file
@@ -0,0 +1,119 @@
|
||||
v2.7.1 (2014-09-18)
|
||||
-------------------
|
||||
- [#53] - removed doublespace from sudoer.erb template
|
||||
|
||||
v2.7.0 (2014-08-08)
|
||||
-------------------
|
||||
- [#44] Add basic ChefSpec matchers
|
||||
|
||||
v2.6.0 (2014-05-15)
|
||||
-------------------
|
||||
- [COOK-4612] Add support for the command alias (Cmnd_Alias) directive
|
||||
- [COOK-4637] - handle duplicate resources in LWRP
|
||||
|
||||
|
||||
v2.5.2 (2014-02-27)
|
||||
-------------------
|
||||
Bumping version for toolchain sanity
|
||||
|
||||
|
||||
v2.5.0 (2014-02-27)
|
||||
-------------------
|
||||
Bumping to 2.5.0
|
||||
|
||||
|
||||
v2.4.2 (2014-02-27)
|
||||
-------------------
|
||||
[COOK-4350] - Fix issue with "Defaults" line in sudoer.erb
|
||||
|
||||
|
||||
v2.4.0 (2014-02-18)
|
||||
-------------------
|
||||
### Bug
|
||||
- **[COOK-4225](https://tickets.opscode.com/browse/COOK-4225)** - Mac OS X: /etc/sudoers: syntax error when include_sudoers_d is true
|
||||
|
||||
### Improvement
|
||||
- **[COOK-4014](https://tickets.opscode.com/browse/COOK-4014)** - It should be possible to remove the 'sysadmin' group setting from /etc/sudoers
|
||||
- **[COOK-3643](https://tickets.opscode.com/browse/COOK-3643)** - FreeBSD support for sudo cookbook
|
||||
|
||||
### New Feature
|
||||
- **[COOK-3409](https://tickets.opscode.com/browse/COOK-3409)** - enhance sudo lwrp's default template to allow defining default user parameters
|
||||
|
||||
|
||||
v2.3.0
|
||||
------
|
||||
### Improvement
|
||||
- **[COOK-3843](https://tickets.opscode.com/browse/COOK-3843)** - Make cookbook 'sudo' compatible with Mac OS X
|
||||
|
||||
|
||||
v2.2.2
|
||||
------
|
||||
### Improvement
|
||||
- **[COOK-3653](https://tickets.opscode.com/browse/COOK-3653)** - Change template attribute to kind_of String
|
||||
- **[COOK-3572](https://tickets.opscode.com/browse/COOK-3572)** - Add Test Kitchen, Specs, and Travis CI
|
||||
|
||||
### Bug
|
||||
- **[COOK-3610](https://tickets.opscode.com/browse/COOK-3610)** - Document "Runas" attribute not described in the LWRP Attributes section
|
||||
- **[COOK-3431](https://tickets.opscode.com/browse/COOK-3431)** - Validate correctly with `visudo`
|
||||
|
||||
|
||||
v2.2.0
|
||||
------
|
||||
### New Feature
|
||||
- **[COOK-3056](https://tickets.opscode.com/browse/COOK-3056)** - Allow custom sudoers config prefix
|
||||
|
||||
v2.1.4
|
||||
------
|
||||
This is a bugfix for 11.6.0 compatibility, as we're not monkey-patching Erubis::Context.
|
||||
|
||||
### Bug
|
||||
- [COOK-3399]: Remove node attribute in comment of sudoers templates
|
||||
|
||||
v2.1.2
|
||||
------
|
||||
### Bug
|
||||
- [COOK-2388]: Chef::ShellOut is deprecated, please use Mixlib::ShellOut
|
||||
- [COOK-2814]: Incorrect syntax in README example
|
||||
|
||||
v2.1.0
|
||||
------
|
||||
* [COOK-2388] - Chef::ShellOut is deprecated, please use Mixlib::ShellOut
|
||||
* [COOK-2427] - unable to install users cookbook in chef 11
|
||||
* [COOK-2814] - Incorrect syntax in README example
|
||||
|
||||
v2.0.4
|
||||
------
|
||||
* [COOK-2078] - syntax highlighting README on GitHub flavored markdown
|
||||
* [COOK-2119] - LWRP template doesn't support multiple commands in a single block.
|
||||
|
||||
v2.0.2
|
||||
------
|
||||
* [COOK-2109] - lwrp uses incorrect action on underlying file resource.
|
||||
|
||||
v2.0.0
|
||||
------
|
||||
This is a major release because the LWRP's "nopasswd" attribute is changed from true to false, to match the passwordless attribute in the attributes file. This requires a change to people's LWRP use.
|
||||
|
||||
* [COOK-2085] - Incorrect default value in the sudo LWRP's nopasswd attribute
|
||||
|
||||
v1.3.0
|
||||
------
|
||||
* [COOK-1892] - Revamp sudo cookbook and LWRP
|
||||
* [COOK-2022] - add an attribute for setting /etc/sudoers Defaults
|
||||
|
||||
v1.2.2
|
||||
------
|
||||
* [COOK-1628] - set host in sudo lwrp
|
||||
|
||||
v1.2.0
|
||||
------
|
||||
* [COOK-1314] - default package action is now :install instead of :upgrade
|
||||
* [COOK-1549] - Preserve SSH agent credentials upon sudo using an attribute
|
||||
|
||||
v1.1.0
|
||||
------
|
||||
* [COOK-350] - LWRP to manage sudo files via includedir (/etc/sudoers.d)
|
||||
|
||||
v1.0.2
|
||||
------
|
||||
* [COOK-903] - freebsd support
|
||||
307
cookbooks/sudo/README.md
Normal file
307
cookbooks/sudo/README.md
Normal file
@@ -0,0 +1,307 @@
|
||||
sudo cookbook
|
||||
=============
|
||||
[](http://travis-ci.org/opscode-cookbooks/sudo)
|
||||
|
||||
The Chef `sudo` cookbook installs the `sudo` package and configures the `/etc/sudoers` file.
|
||||
|
||||
It also exposes an LWRP for adding and managing sudoers.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
The platform has a package named `sudo` and the `sudoers` file is `/etc/sudoers`.
|
||||
|
||||
|
||||
Attributes
|
||||
----------
|
||||
- `node['authorization']['sudo']['groups']` - groups to enable sudo access (default: `[ "sysadmin" ]`)
|
||||
- `node['authorization']['sudo']['users']` - users to enable sudo access (default: `[]`)
|
||||
- `node['authorization']['sudo']['passwordless']` - use passwordless sudo (default: `false`)
|
||||
- `node['authorization']['sudo']['include_sudoers_d']` - include and manager `/etc/sudoers.d` (default: `false`)
|
||||
- `node['authorization']['sudo']['agent_forwarding']` - preserve `SSH_AUTH_SOCK` when sudoing (default: `false`)
|
||||
- `node['authorization']['sudo']['sudoers_defaults']` - Array of `Defaults` entries to configure in `/etc/sudoers`
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
#### Attributes
|
||||
To use attributes for defining sudoers, set the attributes above on the node (or role) itself:
|
||||
|
||||
```json
|
||||
{
|
||||
"default_attributes": {
|
||||
"authorization": {
|
||||
"sudo": {
|
||||
"groups": ["admin", "wheel", "sysadmin"],
|
||||
"users": ["jerry", "greg"],
|
||||
"passwordless": "true"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```ruby
|
||||
# roles/example.rb
|
||||
default_attributes(
|
||||
"authorization" => {
|
||||
"sudo" => {
|
||||
"groups" => ["admin", "wheel", "sysadmin"],
|
||||
"users" => ["jerry", "greg"],
|
||||
"passwordless" => true
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
**Note that the template for the sudoers file has the group "sysadmin" with ALL:ALL permission, though the group by default does not exist.**
|
||||
|
||||
#### Sudoers Defaults
|
||||
|
||||
Configure a node attribute,
|
||||
`node['authorization']['sudo']['sudoers_defaults']` as an array of
|
||||
`Defaults` entries to configure in `/etc/sudoers`. A list of examples
|
||||
for common platforms is listed below:
|
||||
|
||||
*Debian*
|
||||
```ruby
|
||||
node.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset']
|
||||
```
|
||||
|
||||
*Ubuntu 10.04*
|
||||
```ruby
|
||||
node.default['authorization']['sudo']['sudoers_defaults'] = ['env_reset']
|
||||
```
|
||||
|
||||
*Ubuntu 12.04*
|
||||
```ruby
|
||||
node.default['authorization']['sudo']['sudoers_defaults'] = [
|
||||
'env_reset',
|
||||
'secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"'
|
||||
]
|
||||
```
|
||||
|
||||
*FreeBSD*
|
||||
```ruby
|
||||
node.default['authorization']['sudo']['sudoers_defaults'] = [
|
||||
'env_reset',
|
||||
'secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"'
|
||||
]
|
||||
```
|
||||
|
||||
*RHEL family 5.x*
|
||||
The version of sudo in RHEL 5 may not support `+=`, as used in `env_keep`, so its a single string.
|
||||
|
||||
```ruby
|
||||
node.default['authorization']['sudo']['sudoers_defaults'] = [
|
||||
'!visiblepw',
|
||||
'env_reset',
|
||||
'env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
|
||||
LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
|
||||
LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
|
||||
LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \
|
||||
LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
|
||||
_XKB_CHARSET XAUTHORITY"'
|
||||
]
|
||||
```
|
||||
|
||||
*RHEL family 6.x*
|
||||
```ruby
|
||||
node.default['authorization']['sudo']['sudoers_defaults'] = [
|
||||
'!visiblepw',
|
||||
'env_reset',
|
||||
'env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR LS_COLORS"',
|
||||
'env_keep += "MAIL PS1 PS2 QTDIR USERNAME LANG LC_ADDRESS LC_CTYPE"',
|
||||
'env_keep += "LC_COLLATE LC_IDENTIFICATION LC_MEASUREMENT LC_MESSAGES"',
|
||||
'env_keep += "LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE"',
|
||||
'env_keep += "LC_TIME LC_ALL LANGUAGE LINGUAS _XKB_CHARSET XAUTHORITY"',
|
||||
'env_keep += "HOME"',
|
||||
'always_set_home',
|
||||
'secure_path = /sbin:/bin:/usr/sbin:/usr/bin'
|
||||
]
|
||||
```
|
||||
|
||||
*Mac OS X*
|
||||
```ruby
|
||||
node.default['authorization']['sudo']['sudoers_defaults'] = [
|
||||
'env_reset',
|
||||
'env_keep += "BLOCKSIZE"',
|
||||
'env_keep += "COLORFGBG COLORTERM"',
|
||||
'env_keep += "__CF_USER_TEXT_ENCODING"',
|
||||
'env_keep += "CHARSET LANG LANGUAGE LC_ALL LC_COLLATE LC_CTYPE"',
|
||||
'env_keep += "LC_MESSAGES LC_MONETARY LC_NUMERIC LC_TIME"',
|
||||
'env_keep += "LINES COLUMNS"',
|
||||
'env_keep += "LSCOLORS"',
|
||||
'env_keep += "TZ"',
|
||||
'env_keep += "DISPLAY XAUTHORIZATION XAUTHORITY"',
|
||||
'env_keep += "EDITOR VISUAL"',
|
||||
'env_keep += "HOME MAIL"'
|
||||
]
|
||||
```
|
||||
|
||||
#### LWRP
|
||||
**Note** Sudo version 1.7.2 or newer is required to use the sudo LWRP as it relies on the "#includedir" directive introduced in version 1.7.2. The recipe does not enforce installing the version. To use this LWRP, set `node['authorization']['sudo']['include_sudoers_d']` to `true`.
|
||||
|
||||
There are two ways for rendering a sudoer-fragment using this LWRP:
|
||||
|
||||
1. Using the built-in template
|
||||
2. Using a custom, cookbook-level template
|
||||
|
||||
Both methods will create the `/etc/sudoers.d/#{username}` file with the correct permissions.
|
||||
|
||||
The LWRP also performs **fragment validation**. If a sudoer-fragment is not valid, the Chef run will throw an exception and fail. This ensures that your sudoers file is always valid and cannot become corrupt (from this cookbook).
|
||||
|
||||
Example using the built-in template:
|
||||
|
||||
```ruby
|
||||
sudo 'tomcat' do
|
||||
user "%tomcat" # or a username
|
||||
runas 'app_user' # or 'app_user:tomcat'
|
||||
commands ['/etc/init.d/tomcat restart']
|
||||
end
|
||||
```
|
||||
|
||||
```ruby
|
||||
sudo 'tomcat' do
|
||||
template 'my_tomcat.erb' # local cookbook template
|
||||
variables :cmds => ['/etc/init.d/tomcat restart']
|
||||
end
|
||||
```
|
||||
|
||||
In either case, the following file would be generated in `/etc/sudoers.d/tomcat`
|
||||
|
||||
```bash
|
||||
# This file is managed by Chef for node.example.com
|
||||
# Do NOT modify this file directly.
|
||||
|
||||
%tomcat ALL=(app_user) /etc/init.d/tomcat restart
|
||||
```
|
||||
|
||||
##### LWRP Attributes
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Attribute</th>
|
||||
<th>Description</th>
|
||||
<th>Example</th>
|
||||
<th>Default</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>name</td>
|
||||
<td>name of the `/etc/sudoers.d` file</td>
|
||||
<td><tt>restart-tomcat</tt></td>
|
||||
<td>current resource name</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>commands</td>
|
||||
<td>array of commands this sudoer can execute</td>
|
||||
<td><tt>['/etc/init.d/tomcat restart']</tt></td>
|
||||
<td><tt>['ALL']</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>group</td>
|
||||
<td>group to provide sudo privileges to, except `%` is prepended to the name in
|
||||
case it is not already</td>
|
||||
<td><tt>%admin</tt></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>nopasswd</td>
|
||||
<td>supply a password to invoke sudo</td>
|
||||
<td><tt>true</tt></td>
|
||||
<td><tt>false</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>runas</td>
|
||||
<td>User the command(s) can be run as</td>
|
||||
<td><tt>root</tt></td>
|
||||
<td><tt>ALL</tt></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>template</td>
|
||||
<td>the erb template to render instead of the default</td>
|
||||
<td><tt>restart-tomcat.erb</tt></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>user</td>
|
||||
<td>user to provide sudo privileges to</td>
|
||||
<td><tt>tomcat</tt></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>defaults</td>
|
||||
<td>array of defaults this user has</td>
|
||||
<td><tt>['!requiretty','env_reset']</tt></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>variables</td>
|
||||
<td>the variables to pass to the custom template</td>
|
||||
<td><tt>:commands => ['/etc/init.d/tomcat restart']</tt></td>
|
||||
<td></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
**If you use the template attribute, all other attributes will be ignored except for the variables attribute.**
|
||||
|
||||
|
||||
Development
|
||||
-----------
|
||||
This section details "quick development" steps. For a detailed explanation, see [[Contributing.md]].
|
||||
|
||||
1. Clone this repository from GitHub:
|
||||
|
||||
$ git clone git@github.com:opscode-cookbooks/sudo.git
|
||||
|
||||
2. Create a git branch
|
||||
|
||||
$ git checkout -b my_bug_fix
|
||||
|
||||
3. Install dependencies:
|
||||
|
||||
$ bundle install
|
||||
|
||||
4. Make your changes/patches/fixes, committing appropiately
|
||||
5. **Write tests**
|
||||
6. Run the tests:
|
||||
- `bundle exec foodcritic -f any .`
|
||||
- `bundle exec rspec`
|
||||
- `bundle exec rubocop`
|
||||
- `bundle exec kitchen test`
|
||||
|
||||
In detail:
|
||||
- Foodcritic will catch any Chef-specific style errors
|
||||
- RSpec will run the unit tests
|
||||
- Rubocop will check for Ruby-specific style errors
|
||||
- Test Kitchen will run and converge the recipes
|
||||
|
||||
|
||||
|
||||
|
||||
License and Authors
|
||||
-------------------
|
||||
- Author:: Bryan W. Berry <bryan.berry@gmail.com>
|
||||
- Author:: Adam Jacob <adam@opscode.com>
|
||||
- Author:: Seth Chisamore <schisamo@opscode.com>
|
||||
- Author:: Seth Vargo <sethvargo@gmail.com>
|
||||
|
||||
```text
|
||||
Copyright 2009-2012, Opscode, Inc.
|
||||
|
||||
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.
|
||||
```
|
||||
35
cookbooks/sudo/attributes/default.rb
Normal file
35
cookbooks/sudo/attributes/default.rb
Normal file
@@ -0,0 +1,35 @@
|
||||
#
|
||||
# Cookbook Name:: sudo
|
||||
# Attribute File:: default
|
||||
#
|
||||
# Copyright 2008-2013, Opscode, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
default['authorization']['sudo']['groups'] = ['sysadmin']
|
||||
default['authorization']['sudo']['users'] = []
|
||||
default['authorization']['sudo']['passwordless'] = false
|
||||
default['authorization']['sudo']['include_sudoers_d'] = false
|
||||
default['authorization']['sudo']['agent_forwarding'] = false
|
||||
default['authorization']['sudo']['sudoers_defaults'] = ['!lecture,tty_tickets,!fqdn']
|
||||
default['authorization']['sudo']['command_aliases'] = []
|
||||
|
||||
case node['platform_family']
|
||||
when 'smartos'
|
||||
default['authorization']['sudo']['prefix'] = '/opt/local/etc'
|
||||
when 'freebsd'
|
||||
default['authorization']['sudo']['prefix'] = '/usr/local/etc'
|
||||
else
|
||||
default['authorization']['sudo']['prefix'] = '/etc'
|
||||
end
|
||||
17
cookbooks/sudo/files/default/README
Normal file
17
cookbooks/sudo/files/default/README
Normal file
@@ -0,0 +1,17 @@
|
||||
#
|
||||
# As of Debian version 1.7.2p1-1, the default /etc/sudoers file created on
|
||||
# installation of the package now includes the directive:
|
||||
#
|
||||
# #includedir /etc/sudoers.d
|
||||
#
|
||||
# This will cause sudo to read and parse any files in the /etc/sudoers.d
|
||||
# directory that do not end in '~' or contain a '.' character.
|
||||
#
|
||||
# Note that there must be at least one file in the sudoers.d directory (this
|
||||
# one will do), and all files in this directory should be mode 0440.
|
||||
#
|
||||
# Note also, that because sudoers contents can vary widely, no attempt is
|
||||
# made to add this directive to existing sudoers files on upgrade. Feel free
|
||||
# to add the above directive to the end of your /etc/sudoers file to enable
|
||||
# this functionality for existing installations if you wish!
|
||||
#
|
||||
9
cookbooks/sudo/libraries/matchers.rb
Normal file
9
cookbooks/sudo/libraries/matchers.rb
Normal file
@@ -0,0 +1,9 @@
|
||||
if defined?(ChefSpec)
|
||||
def install_sudo(resource_name)
|
||||
ChefSpec::Matchers::ResourceMatcher.new(:sudo, :install, resource_name)
|
||||
end
|
||||
|
||||
def remove_sudo(resource_name)
|
||||
ChefSpec::Matchers::ResourceMatcher.new(:sudo, :remove, resource_name)
|
||||
end
|
||||
end
|
||||
71
cookbooks/sudo/metadata.json
Normal file
71
cookbooks/sudo/metadata.json
Normal file
@@ -0,0 +1,71 @@
|
||||
{
|
||||
"name": "sudo",
|
||||
"version": "2.7.1",
|
||||
"description": "Installs sudo and configures /etc/sudoers",
|
||||
"long_description": "",
|
||||
"maintainer": "Opscode, Inc.",
|
||||
"maintainer_email": "cookbooks@opscode.com",
|
||||
"license": "Apache 2.0",
|
||||
"platforms": {
|
||||
"redhat": ">= 0.0.0",
|
||||
"centos": ">= 0.0.0",
|
||||
"fedora": ">= 0.0.0",
|
||||
"ubuntu": ">= 0.0.0",
|
||||
"debian": ">= 0.0.0",
|
||||
"freebsd": ">= 0.0.0",
|
||||
"mac_os_x": ">= 0.0.0"
|
||||
},
|
||||
"dependencies": {
|
||||
},
|
||||
"recommendations": {
|
||||
},
|
||||
"suggestions": {
|
||||
},
|
||||
"conflicting": {
|
||||
},
|
||||
"providing": {
|
||||
},
|
||||
"replacing": {
|
||||
},
|
||||
"attributes": {
|
||||
"authorization": {
|
||||
"display_name": "Authorization",
|
||||
"description": "Hash of Authorization attributes",
|
||||
"type": "hash"
|
||||
},
|
||||
"authorization/sudo": {
|
||||
"display_name": "Authorization Sudoers",
|
||||
"description": "Hash of Authorization/Sudo attributes",
|
||||
"type": "hash"
|
||||
},
|
||||
"authorization/sudo/users": {
|
||||
"display_name": "Sudo Users",
|
||||
"description": "Users who are allowed sudo ALL",
|
||||
"type": "array",
|
||||
"default": ""
|
||||
},
|
||||
"authorization/sudo/groups": {
|
||||
"display_name": "Sudo Groups",
|
||||
"description": "Groups who are allowed sudo ALL",
|
||||
"type": "array",
|
||||
"default": ""
|
||||
},
|
||||
"authorization/sudo/passwordless": {
|
||||
"display_name": "Passwordless Sudo",
|
||||
"description": "",
|
||||
"type": "string",
|
||||
"default": "false"
|
||||
},
|
||||
"authorization/sudo/include_sudoers_d": {
|
||||
"display_name": "Include sudoers.d",
|
||||
"description": "Whether to create the sudoers.d includedir",
|
||||
"type": "string",
|
||||
"default": "false"
|
||||
}
|
||||
},
|
||||
"groupings": {
|
||||
},
|
||||
"recipes": {
|
||||
"sudo": "Installs sudo and configures /etc/sudoers"
|
||||
}
|
||||
}
|
||||
46
cookbooks/sudo/metadata.rb
Normal file
46
cookbooks/sudo/metadata.rb
Normal file
@@ -0,0 +1,46 @@
|
||||
name 'sudo'
|
||||
maintainer 'Opscode, Inc.'
|
||||
maintainer_email 'cookbooks@opscode.com'
|
||||
license 'Apache 2.0'
|
||||
description 'Installs sudo and configures /etc/sudoers'
|
||||
version '2.7.1'
|
||||
|
||||
recipe 'sudo', 'Installs sudo and configures /etc/sudoers'
|
||||
|
||||
%w(redhat centos fedora ubuntu debian freebsd mac_os_x).each do |os|
|
||||
supports os
|
||||
end
|
||||
|
||||
attribute 'authorization',
|
||||
:display_name => 'Authorization',
|
||||
:description => 'Hash of Authorization attributes',
|
||||
:type => 'hash'
|
||||
|
||||
attribute 'authorization/sudo',
|
||||
:display_name => 'Authorization Sudoers',
|
||||
:description => 'Hash of Authorization/Sudo attributes',
|
||||
:type => 'hash'
|
||||
|
||||
attribute 'authorization/sudo/users',
|
||||
:display_name => 'Sudo Users',
|
||||
:description => 'Users who are allowed sudo ALL',
|
||||
:type => 'array',
|
||||
:default => ''
|
||||
|
||||
attribute 'authorization/sudo/groups',
|
||||
:display_name => 'Sudo Groups',
|
||||
:description => 'Groups who are allowed sudo ALL',
|
||||
:type => 'array',
|
||||
:default => ''
|
||||
|
||||
attribute 'authorization/sudo/passwordless',
|
||||
:display_name => 'Passwordless Sudo',
|
||||
:description => '',
|
||||
:type => 'string',
|
||||
:default => 'false'
|
||||
|
||||
attribute 'authorization/sudo/include_sudoers_d',
|
||||
:display_name => 'Include sudoers.d',
|
||||
:description => 'Whether to create the sudoers.d includedir',
|
||||
:type => 'string',
|
||||
:default => 'false'
|
||||
148
cookbooks/sudo/providers/default.rb
Normal file
148
cookbooks/sudo/providers/default.rb
Normal file
@@ -0,0 +1,148 @@
|
||||
#
|
||||
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
|
||||
# Author:: Seth Vargo (<sethvargo@gmail.com>)
|
||||
# Cookbook Name:: sudo
|
||||
# Provider:: default
|
||||
#
|
||||
# Copyright 2011, Bryan w. Berry
|
||||
# Copyright 2012, Seth Vargo
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# This LWRP supports whyrun mode
|
||||
def whyrun_supported?
|
||||
true
|
||||
end
|
||||
|
||||
# Ensure that the inputs are valid (we cannot just use the resource for this)
|
||||
def check_inputs(user, group, foreign_template, foreign_vars)
|
||||
# if group, user, and template are nil, throw an exception
|
||||
if user.nil? && group.nil? && foreign_template.nil?
|
||||
fail 'You must provide a user, group, or template!'
|
||||
elsif !user.nil? && !group.nil? && !template.nil?
|
||||
fail 'You cannot specify user, group, and template!'
|
||||
end
|
||||
end
|
||||
|
||||
# Validate the given resource (template) by writing it out to a file and then
|
||||
# ensuring that file's contents pass `visudo -c`
|
||||
def validate_fragment!(resource)
|
||||
file = Tempfile.new('sudoer')
|
||||
|
||||
begin
|
||||
file.write(capture(resource))
|
||||
file.rewind
|
||||
|
||||
cmd = Mixlib::ShellOut.new("visudo -cf #{file.path}").run_command
|
||||
unless cmd.exitstatus == 0
|
||||
Chef::Log.error("Fragment validation failed: \n\n")
|
||||
Chef::Log.error(file.read)
|
||||
Chef::Application.fatal!("Template #{file.path} failed fragment validation!")
|
||||
end
|
||||
ensure
|
||||
file.close
|
||||
file.unlink
|
||||
end
|
||||
end
|
||||
|
||||
# Render a single sudoer template. This method has two modes:
|
||||
# 1. using the :template option - the user can specify a template
|
||||
# that exists in the local cookbook for writing out the attributes
|
||||
# 2. using the built-in template (recommended) - simply pass the
|
||||
# desired variables to the method and the correct template will be
|
||||
# written out for the user
|
||||
def render_sudoer
|
||||
if new_resource.template
|
||||
Chef::Log.debug('Template attribute provided, all other attributes ignored.')
|
||||
|
||||
resource = template "#{node['authorization']['sudo']['prefix']}/sudoers.d/#{new_resource.name}" do
|
||||
source new_resource.template
|
||||
owner 'root'
|
||||
group node['root_group']
|
||||
mode '0440'
|
||||
variables new_resource.variables
|
||||
action :nothing
|
||||
end
|
||||
else
|
||||
sudoer = new_resource.user || "%#{new_resource.group}".squeeze('%')
|
||||
|
||||
resource = template "#{node['authorization']['sudo']['prefix']}/sudoers.d/#{new_resource.name}" do
|
||||
source 'sudoer.erb'
|
||||
cookbook 'sudo'
|
||||
owner 'root'
|
||||
group node['root_group']
|
||||
mode '0440'
|
||||
variables :sudoer => sudoer,
|
||||
:host => new_resource.host,
|
||||
:runas => new_resource.runas,
|
||||
:nopasswd => new_resource.nopasswd,
|
||||
:commands => new_resource.commands,
|
||||
:command_aliases => new_resource.command_aliases,
|
||||
:defaults => new_resource.defaults
|
||||
action :nothing
|
||||
end
|
||||
end
|
||||
|
||||
# Ensure that, adding this sudoer, would not break sudo
|
||||
validate_fragment!(resource)
|
||||
|
||||
resource.run_action(:create)
|
||||
|
||||
# Return whether the resource was updated so we can notify in the action
|
||||
resource.updated_by_last_action?
|
||||
end
|
||||
|
||||
# Default action - install a single sudoer
|
||||
action :install do
|
||||
target = "#{node['authorization']['sudo']['prefix']}/sudoers.d/"
|
||||
|
||||
unless ::File.exists?(target)
|
||||
sudoers_dir = directory target
|
||||
sudoers_dir.run_action(:create)
|
||||
end
|
||||
|
||||
new_resource.updated_by_last_action(true) if render_sudoer
|
||||
end
|
||||
|
||||
# Removes a user from the sudoers group
|
||||
action :remove do
|
||||
resource = file "#{node['authorization']['sudo']['prefix']}/sudoers.d/#{new_resource.name}" do
|
||||
action :nothing
|
||||
end
|
||||
resource.run_action(:delete)
|
||||
new_resource.updated_by_last_action(true) if resource.updated_by_last_action?
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Capture a template to a string
|
||||
def capture(template)
|
||||
context = {}
|
||||
context.merge!(template.variables)
|
||||
context[:node] = node
|
||||
|
||||
eruby = Erubis::Eruby.new(::File.read(template_location(template)))
|
||||
eruby.evaluate(context)
|
||||
end
|
||||
|
||||
# Find the template
|
||||
def template_location(template)
|
||||
if template.local
|
||||
template.source
|
||||
else
|
||||
context = template.instance_variable_get('@run_context')
|
||||
cookbook = context.cookbook_collection[template.cookbook || template.cookbook_name]
|
||||
cookbook.preferred_filename_on_disk_location(node, :templates, template.source)
|
||||
end
|
||||
end
|
||||
55
cookbooks/sudo/recipes/default.rb
Normal file
55
cookbooks/sudo/recipes/default.rb
Normal file
@@ -0,0 +1,55 @@
|
||||
#
|
||||
# Cookbook Name:: sudo
|
||||
# Recipe:: default
|
||||
#
|
||||
# Copyright 2008-2013, Opscode, Inc.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
prefix = node['authorization']['sudo']['prefix']
|
||||
|
||||
package 'sudo' do
|
||||
not_if 'which sudo'
|
||||
end
|
||||
|
||||
if node['authorization']['sudo']['include_sudoers_d']
|
||||
directory "#{prefix}/sudoers.d" do
|
||||
mode '0755'
|
||||
owner 'root'
|
||||
group node['root_group']
|
||||
end
|
||||
|
||||
cookbook_file "#{prefix}/sudoers.d/README" do
|
||||
source 'README'
|
||||
mode '0440'
|
||||
owner 'root'
|
||||
group node['root_group']
|
||||
end
|
||||
end
|
||||
|
||||
template "#{prefix}/sudoers" do
|
||||
source 'sudoers.erb'
|
||||
mode '0440'
|
||||
owner 'root'
|
||||
group node['root_group']
|
||||
variables(
|
||||
:sudoers_groups => node['authorization']['sudo']['groups'],
|
||||
:sudoers_users => node['authorization']['sudo']['users'],
|
||||
:passwordless => node['authorization']['sudo']['passwordless'],
|
||||
:include_sudoers_d => node['authorization']['sudo']['include_sudoers_d'],
|
||||
:agent_forwarding => node['authorization']['sudo']['agent_forwarding'],
|
||||
:sudoers_defaults => node['authorization']['sudo']['sudoers_defaults'],
|
||||
:command_aliases => node['authorization']['sudo']['command_aliases']
|
||||
)
|
||||
end
|
||||
50
cookbooks/sudo/resources/default.rb
Normal file
50
cookbooks/sudo/resources/default.rb
Normal file
@@ -0,0 +1,50 @@
|
||||
#
|
||||
# Author:: Bryan W. Berry (<bryan.berry@gmail.com>)
|
||||
# Cookbook Name:: sudo
|
||||
# Resource:: default
|
||||
#
|
||||
# Copyright 2011-2013, Bryan w. Berry
|
||||
#
|
||||
# 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.
|
||||
|
||||
actions :install, :remove
|
||||
default_action :install
|
||||
|
||||
attribute :user, :kind_of => String, :default => nil
|
||||
attribute :group, :kind_of => String, :default => nil
|
||||
attribute :commands, :kind_of => Array, :default => ['ALL']
|
||||
attribute :host, :kind_of => String, :default => 'ALL'
|
||||
attribute :runas, :kind_of => String, :default => 'ALL'
|
||||
attribute :nopasswd, :equal_to => [true, false], :default => false
|
||||
attribute :template, :kind_of => String, :default => nil
|
||||
attribute :variables, :kind_of => Hash, :default => nil
|
||||
attribute :defaults, :kind_of => Array, :default => []
|
||||
attribute :command_aliases, :kind_of => Array, :default => []
|
||||
|
||||
# Set default for the supports attribute in initializer since it is
|
||||
# a 'reserved' attribute name
|
||||
def initialize(*args)
|
||||
super
|
||||
@action = :install
|
||||
@supports = { :report => true, :exception => true }
|
||||
end
|
||||
|
||||
state_attrs :commands,
|
||||
:group,
|
||||
:host,
|
||||
:nopasswd,
|
||||
:runas,
|
||||
:template,
|
||||
:user,
|
||||
:variables,
|
||||
:command_aliases
|
||||
14
cookbooks/sudo/templates/default/sudoer.erb
Normal file
14
cookbooks/sudo/templates/default/sudoer.erb
Normal file
@@ -0,0 +1,14 @@
|
||||
# This file is managed by Chef.
|
||||
# Do NOT modify this file directly.
|
||||
|
||||
<% @command_aliases.each do |a| -%>
|
||||
Cmnd_Alias <%= a[:name].upcase %> = <%= a[:command_list].join(', ') %>
|
||||
<% end -%>
|
||||
|
||||
<% @commands.each do |command| -%>
|
||||
<%= @sudoer %> <%= @host %>=(<%= @runas %>) <%= 'NOPASSWD:' if @nopasswd %><%= command %>
|
||||
<% end -%>
|
||||
|
||||
<% unless @defaults.empty? %>
|
||||
Defaults:<%= @sudoer %> <%= @defaults.join(',') %>
|
||||
<% end -%>
|
||||
27
cookbooks/sudo/templates/default/sudoers.erb
Normal file
27
cookbooks/sudo/templates/default/sudoers.erb
Normal file
@@ -0,0 +1,27 @@
|
||||
# This file is managed by Chef.
|
||||
# Do NOT modify this file directly.
|
||||
|
||||
<% @sudoers_defaults.each do |defaults| -%>
|
||||
Defaults <%= defaults %>
|
||||
<% end -%>
|
||||
<% if @agent_forwarding -%>
|
||||
Defaults env_keep+=SSH_AUTH_SOCK
|
||||
<% end -%>
|
||||
|
||||
# User privilege specification
|
||||
root ALL=(ALL) ALL
|
||||
|
||||
<% @command_aliases.each do |a| -%>
|
||||
Cmnd_Alias <%= a[:name].upcase %> = <%= a[:command_list].join(', ') %>
|
||||
<% end -%>
|
||||
|
||||
<% @sudoers_users.each do |user| -%>
|
||||
<%= user %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
|
||||
<% end -%>
|
||||
|
||||
<% @sudoers_groups.each do |group| -%>
|
||||
# Members of the group '<%= group %>' may gain root privileges
|
||||
%<%= group %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
|
||||
<% end -%>
|
||||
|
||||
<%= "#includedir #{node['authorization']['sudo']['prefix']}/sudoers.d" if @include_sudoers_d %>
|
||||
23
cookbooks/sudo/templates/mac_os_x/sudoers.erb
Normal file
23
cookbooks/sudo/templates/mac_os_x/sudoers.erb
Normal file
@@ -0,0 +1,23 @@
|
||||
# This file is managed by Chef.
|
||||
# Do NOT modify this file directly.
|
||||
|
||||
<% @sudoers_defaults.each do |defaults| -%>
|
||||
Defaults <%= defaults %>
|
||||
<% end -%>
|
||||
<% if @agent_forwarding -%>
|
||||
Defaults env_keep+=SSH_AUTH_SOCK
|
||||
<% end -%>
|
||||
|
||||
# User privilege specification
|
||||
root ALL=(ALL) ALL
|
||||
%admin ALL=(ALL) ALL
|
||||
<% @sudoers_users.each do |user| -%>
|
||||
<%= user %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
|
||||
<% end -%>
|
||||
|
||||
<% @sudoers_groups.each do |group| -%>
|
||||
# Members of the group '<%= group %>' may gain root privileges
|
||||
%<%= group %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL
|
||||
<% end -%>
|
||||
|
||||
<%= "#includedir #{node['authorization']['sudo']['prefix']}/sudoers.d" if @include_sudoers_d %>
|
||||
Reference in New Issue
Block a user