Skip to content

Commit 2960760

Browse files
authored
Merge pull request #1 from Stromweld/working
working copy
2 parents 8045b41 + d51ae28 commit 2960760

File tree

12 files changed

+1018
-13
lines changed

12 files changed

+1018
-13
lines changed

CHANGELOG.md

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,9 @@
1-
# CHANGELOG for timezone_ii
1+
# CHANGELOG for autopatch_ii
22

3-
## 2.0.0 (4/19/2017)
3+
## 1.0.1 (4/20/2017)
44

5-
- [Corey Hemminger] - changed hash rockets to new hash style
6-
7-
## 1.0.1 (4/18/2017)
8-
9-
- [Corey Hemminger] - fixed windows idempotency
5+
- [Corey Hemminger] - Fixed bugs and tested to be working
106

117
## 1.0.0 (4/18/2017)
128

13-
- [Corey Hemminger] - Initial commit
9+
- [Corey Hemminger] - Initial commit

README.md

Lines changed: 124 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,127 @@
1+
[![Code Climate](https://codeclimate.com/github/Stromweld/autopatch_ii/badges/gpa.svg)](https://codeclimate.com/github/Stromweld/autopatch_ii)
2+
[![Issue Count](https://codeclimate.com/github/Stromweld/autopatch_ii/badges/issue_count.svg)](https://codeclimate.com/github/Stromweld/autopatch_ii)
3+
14
# autopatch_ii
25

3-
TODO: Enter the cookbook description here.
6+
## Description
7+
8+
Chef Cookbook for automatically patching nodes on a specific schedule (weekday, hour, and minute). Handles weekly or monthly patching routines with or without node splay for large environments.
9+
10+
Much of this code was copied from chef cookbook auto-patch written by Brian Flad. I've modified it to work with windows and use windows more flexible task scheduling with some magic to get it to also work with linux cron.
11+
12+
## Requirements
13+
14+
### Platforms
15+
16+
* RHEL based platforms
17+
* Windows
18+
19+
### Cookbooks
20+
21+
* cron
22+
* logrotate
23+
24+
## Attributes
25+
26+
| Attribute | Default | Comment |
27+
| ------------- | ------------- | ------------- |
28+
| ['autopatch_ii']['disable'] | false | Boolean, enable or disable patches |
29+
| ['autopatch_ii']['domain'] | 'example.com' | String, Domain server resides in |
30+
| ['autopatch_ii']['task_username'] | 'SYSTEM' | String, Used only for winows task scheduling |
31+
| ['autopatch_ii']['task_frequency'] | :monthly | Symbol, one of either :monthly or :weekly |
32+
| ['autopatch_ii']['task_frequency_modifier'] | 'THIRD' | String, used to denote which week of the month you want to run the task |
33+
| ['autopatch_ii']['task_months'] | 'JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV' | String, CSV list of short names for months you want the task to run in, * is used for all months |
34+
| ['autopatch_ii']['task_days'] | 'TUE' | String, which days of the week in short form you want the task to run on |
35+
| ['autopatch_ii']['task_start_time'] | '04:00' | String, Military time setting for when to run patches |
36+
| ['autopatch_ii']['working_dir'] | node['os'] == 'windows' ? 'C:\chef_autopatch' : '/var/log/chef_autopatch' | String, Directory for log file and temp files |
37+
| ['autopatch_ii']['download_install_splay_max_seconds'] | 3600 | Integer, Max allowed random time to wait before downloading and installing patches, this way we don't overwhelm on premise patch repo |
38+
| ['autopatch_ii']['email_notification_mode'] | 'Always' | String, whether to send email after patches and before reboot with status of patch install |
39+
| ['autopatch_ii']['email_to_addresses'] | '"[email protected]"' | String, email address for nodes to send the email to |
40+
| ['autopatch_ii']['email_from_address'] | "#{node['hostname']}@example.com" | String, email address the email came from |
41+
| ['autopatch_ii']['email_smtp_server'] | 'smtp.example.com' | String, email server to forward the email to, relay with no authentication is recommended |
42+
| ['autopatch_ii']['auto_reboot_enabled'] | true | Boolean, to reboot the server automatically after patches have been installed or to leave it for manual reboot |
43+
| ['autopatch_ii']['updates_to_skip'] | [] | Array of Strings, package names to skip during patches on linux |
44+
| ['autopatch_ii']['update_command_options'] | '' | String, any additional options to be passed to the yum command on linux |
45+
| ['autopatch_ii']['private_lin_autopatch_disabled_programmatically'] | false | Boolean, DO NOT MODIFY THIS, this is modified programatically based on if cron job should skip this month or not |
46+
47+
## Recipes
48+
49+
* `recipe[autopatch_ii]` configures automatic patching and patches server on first chef-client run
50+
* `recipe[autopatch_ii::firstrun_patches]` creates a lock file and runs patches for the first time, afterwards doesn't run as long as lock file exists on the filesystem.
51+
* `recipe[autopatch_ii::linux]` creates cron job and sets up autopatch scripts
52+
* `recipe[autopatch_ii::windows]` creates windows task and sets up autopatch scripts
53+
54+
## Usage
55+
56+
* Change any attributes to fit your patching cycle
57+
* Add `recipe[autopatch_ii]` to your node's run list
58+
59+
### Weekly automatic patching
60+
61+
Just use the `node["autopatch_ii"]['task_frequency'] = :weekly` attribute to override the monthly setting.
62+
63+
### Automatic patching of large numbers of nodes
64+
65+
If you're auto patching many nodes at once, you can optionally modify the splay to prevent denial of service against your network, update server(s), and resources:
66+
67+
* Adding `node["autopatch_ii"]["splay"]`
68+
69+
### Using roles to specify auto patching groups
70+
71+
If you'd like to specify groups of nodes for auto patching, you can setup roles.
72+
73+
Say you want to auto patch some nodes at 8am and some at 10pm on your monthly
74+
"patch day" of the fourth Wednesday every month.
75+
76+
If you have a base role (you do, right?), you can save duplicating attributes
77+
and specify some base information first:
78+
79+
"autopatch_ii" => {
80+
"task_frequency" => :weekly,
81+
"task_days" => 'TUE'
82+
}
83+
84+
Example role that then could be added to 8am nodes:
85+
86+
name "autopatch-0800"
87+
description "Role for automatically patching nodes at 8am on patch day."
88+
default_attributes(
89+
"autopatch_ii" => {
90+
"task_start_time" => '08:00'
91+
}
92+
)
93+
run_list(
94+
"recipe[autopatch_ii]"
95+
)
96+
97+
Example role that then could be added to 10pm nodes:
98+
99+
name "autopatch-2200"
100+
description "Role for automatically patching nodes at 10pm on patch day."
101+
default_attributes(
102+
"autopatch_ii" => {
103+
"task_start_time" => '22:00'
104+
}
105+
)
106+
run_list(
107+
"recipe[autopatch_ii]"
108+
)
109+
110+
### Disabling automatic patching
111+
112+
* Specify `node["autopatch_ii"]["disable"]` to true
113+
* Run chef-client on your node
114+
115+
## License and Author
116+
117+
Author:: Brian Flad (<[email protected]>)
118+
119+
Author:: Corey Hemminger (<[email protected]>)
120+
121+
Copyright:: 2017
122+
123+
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
124+
125+
<http://www.apache.org/licenses/LICENSE-2.0>
4126

127+
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.

attributes/default.rb

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#
2+
# Cookbook:: autopatch_ii
3+
# Attribute:: default
4+
#
5+
# Copyright:: 2017, Corey Hemminger
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
default['autopatch_ii']['disable'] = false
20+
default['autopatch_ii']['domain'] = 'example.com'
21+
default['autopatch_ii']['task_username'] = 'SYSTEM'
22+
default['autopatch_ii']['task_frequency'] = :monthly
23+
default['autopatch_ii']['task_frequency_modifier'] = 'THIRD'
24+
default['autopatch_ii']['task_months'] = 'JAN,FEB,MAR,APR,MAY,JUN,JUL,AUG,SEP,OCT,NOV'
25+
default['autopatch_ii']['task_days'] = 'TUE'
26+
default['autopatch_ii']['task_start_time'] = '04:00'
27+
default['autopatch_ii']['working_dir'] = node['os'] == 'windows' ? 'C:\chef_autopatch' : '/var/log/chef_autopatch'
28+
default['autopatch_ii']['download_install_splay_max_seconds'] = 3600
29+
default['autopatch_ii']['email_notification_mode'] = 'Always'
30+
default['autopatch_ii']['email_to_addresses'] = '"[email protected]"'
31+
default['autopatch_ii']['email_from_address'] = "#{node['hostname']}@example.com"
32+
default['autopatch_ii']['email_smtp_server'] = 'smtp.example.com'
33+
default['autopatch_ii']['auto_reboot_enabled'] = true
34+
default['autopatch_ii']['updates_to_skip'] = []
35+
default['autopatch_ii']['update_command_options'] = ''
36+
37+
# This attribute is used internally - it should never be set outside the cookbook itself, hence the 'private' designation
38+
default['autopatch_ii']['private_lin_autopatch_disabled_programmatically'] = false

libraries/autopatch.rb

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
#
2+
# Cookbook:: autopatch_ii
3+
# Library:: autopatch
4+
#
5+
# Copyright:: 2017, Corey Hemminger
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
require 'date'
20+
21+
# autopatch_ii helper logic
22+
# Chef class
23+
class Chef
24+
# Chef::Recipe class
25+
class Recipe
26+
# Chef::Recipe::AutoPatch class
27+
class AutoPatch
28+
WEEKS = %w(first second third fourth) unless defined?(WEEKS)
29+
WEEKDAYS = %w(sunday monday tuesday wednesday thursday friday saturday) unless defined?(WEEKDAYS)
30+
31+
def self.monthly_date(year, month, monthly_specifier)
32+
Date.new(year, month, monthly_day(year, month, monthly_specifier))
33+
end
34+
35+
def self.monthly_day(year, month, monthly_specifier)
36+
week, weekly_specifier = monthly_specifier.split(' ')
37+
week.downcase!
38+
weekly_specifier.downcase!
39+
Chef::Application.fatal!('Unknown week specified.') unless WEEKS.include?(week)
40+
41+
first_day_occurance = 1
42+
while weekday(weekly_specifier) != Date.new(year, month, first_day_occurance).wday
43+
first_day_occurance += 1
44+
end
45+
first_day_occurance + (WEEKS.index(week) * 7)
46+
end
47+
48+
def self.next_monthly_date(monthly_specifier, hour, minute)
49+
current_time = Time.now
50+
current_patch_time = Time.new(
51+
current_time.year,
52+
current_time.month,
53+
monthly_day(current_time.year, current_time.month, monthly_specifier),
54+
hour,
55+
minute
56+
)
57+
58+
date = if current_time > current_patch_time
59+
if current_time.month == 12
60+
monthly_date(current_time.year + 1, 1, monthly_specifier)
61+
else
62+
monthly_date(current_time.year, current_time.month + 1, monthly_specifier)
63+
end
64+
else
65+
current_patch_time
66+
end
67+
date
68+
end
69+
70+
def self.weekday(weekly_specifier)
71+
Chef::Application.fatal!('Unknown weekday specified.') unless WEEKDAYS.include?(weekly_specifier)
72+
WEEKDAYS.index(weekly_specifier)
73+
end
74+
end
75+
end
76+
end

libraries/autopatch_helpers.rb

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#
2+
# Cookbook:: autopatch_ii
3+
# Library:: autopatch_helpers
4+
#
5+
# Copyright:: 2017, Corey Hemminger
6+
#
7+
# Licensed under the Apache License, Version 2.0 (the "License");
8+
# you may not use this file except in compliance with the License.
9+
# You may obtain a copy of the License at
10+
#
11+
# http://www.apache.org/licenses/LICENSE-2.0
12+
#
13+
# Unless required by applicable law or agreed to in writing, software
14+
# distributed under the License is distributed on an "AS IS" BASIS,
15+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16+
# See the License for the specific language governing permissions and
17+
# limitations under the License.
18+
19+
# Module to translate short name to full name
20+
module AutoPatchHelper
21+
def self.getLCaseWeekdayFromAbbreviation(abbreviatedWeekday)
22+
case abbreviatedWeekday.downcase
23+
when 'mon'
24+
'monday'
25+
when 'tue'
26+
'tuesday'
27+
when 'wed'
28+
'wednesday'
29+
when 'thu'
30+
'thursday'
31+
when 'fri'
32+
'friday'
33+
when 'sat'
34+
'saturday'
35+
when 'sun'
36+
'sunday'
37+
else
38+
raise "Could not determine weekday from abbreviation '#{abbreviatedWeekday}'"
39+
end
40+
end
41+
end

metadata.rb

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,24 @@
44
license 'Apache-2.0'
55
description 'Installs/Configures autopatch_ii'
66
long_description 'Installs/Configures autopatch_ii'
7-
version '0.1.0'
8-
chef_version '>= 12.1' if respond_to?(:chef_version)
7+
version '1.0.1'
8+
chef_version '>= 12.6' if respond_to?(:chef_version)
99

1010
# The `issues_url` points to the location where issues for this cookbook are
1111
# tracked. A `View Issues` link will be displayed on this cookbook's page when
1212
# uploaded to a Supermarket.
1313
#
14-
# issues_url 'https://github.com/<insert_org_here>/autopatch_ii/issues'
14+
issues_url 'https://github.com/Stromweld/autopatch_ii/issues'
1515

1616
# The `source_url` points to the development reposiory for this cookbook. A
1717
# `View Source` link will be displayed on this cookbook's page when uploaded to
1818
# a Supermarket.
1919
#
20-
# source_url 'https://github.com/<insert_org_here>/autopatch_ii'
20+
source_url 'https://github.com/Stromweld/autopatch_ii'
21+
22+
%w(amazon centos fedora redhat scientific oracle windows).each do |os|
23+
supports os
24+
end
25+
26+
depends 'cron'
27+
depends 'logrotate'

recipes/default.rb

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,3 +16,10 @@
1616
# See the License for the specific language governing permissions and
1717
# limitations under the License.
1818

19+
directory 'Auto Patch Working Directory' do
20+
path node['autopatch_ii']['working_dir']
21+
action :create
22+
end
23+
24+
include_recipe 'autopatch_ii::firstrun_patches'
25+
include_recipe node['os'] == 'windows' ? 'autopatch_ii::windows' : 'autopatch_ii::linux'

0 commit comments

Comments
 (0)