diff --git a/README.md b/README.md index 7453e15e..33f5f0c5 100644 --- a/README.md +++ b/README.md @@ -109,6 +109,37 @@ control "blog-1" do end ``` +## Interval Settings + +If you have long running audit profiles that you don't wish to execute on every chef-client run, +you can use the interval recipe instead of the default recipe in your runlist, and set the +following attributes: + +``` +default['audit']['interval']['enabled'] = false +default['audit']['interval']['time'] = 1440 +``` + +The time attribute is in minutes. + +You can enable the interval and set the interval time, along with your desired profiles, + in an environment or role like this: + +```json + + "audit": { + "profiles": { + "base/ssh": true, + "base/linux": true + }, + "interval": { + "enabled": "true", + "time": 1440 + } + } + +``` + Please let us know if you have any [issues](https://github.com/chef-cookbooks/audit/issues), we are happy to help. diff --git a/attributes/interval.rb b/attributes/interval.rb new file mode 100644 index 00000000..04aa0c53 --- /dev/null +++ b/attributes/interval.rb @@ -0,0 +1,22 @@ +# encoding: utf-8 +# +# Author:: Andrew DuFour +# Copyright (c) 2016, Chef Software, 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. +# + +# Interval settings. Please see readme. Time is in minutes. + +default['audit']['interval']['enabled'] = false +default['audit']['interval']['time'] = 1440 diff --git a/libraries/interval.rb b/libraries/interval.rb new file mode 100644 index 00000000..98da705e --- /dev/null +++ b/libraries/interval.rb @@ -0,0 +1,9 @@ +# encoding: utf-8 + +def last_run(profile, interval) + # Calculate when the profile was last run so we delay it's next run if necessary + return false unless ::File.exist?("#{compliance_cache_directory}/#{profile}") + compliance_cache_directory = ::File.join(Chef::Config[:file_cache_path], 'compliance') + lastrun = Time.now - ::File.mtime("#{compliance_cache_directory}/#{profile}") + lastrun < interval +end diff --git a/recipes/interval.rb b/recipes/interval.rb new file mode 100644 index 00000000..17962f1c --- /dev/null +++ b/recipes/interval.rb @@ -0,0 +1,44 @@ +# encoding: utf-8 +# +# Cookbook Name:: compliance +# Recipe:: interval +# +# Copyright 2016 Chef Software, 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. + +interval = node['audit']['interval']['time'] * 60 + +compliance_cache_directory = ::File.join(Chef::Config[:file_cache_path], 'compliance') +directory compliance_cache_directory + +# iterate over all selected profiles + +node['audit']['profiles'].each do |owner_profile, enabled| + next unless enabled + o, p = owner_profile.split('/') + # touch a file so we can keep track of when the profile was last executed + + file "#{compliance_cache_directory}/#{p}" do + action :nothing + end + compliance_profile p do + owner o + action [:fetch, :execute] + not_if { last_run(p, interval) && node['audit']['interval']['enabled'] } + notifies :touch, "file[#{compliance_cache_directory}/#{p}]", :immediately + end +end + +# report the results +compliance_report 'chef-server' if node['audit']['profiles'].values.any? diff --git a/spec/unit/recipes/interval_spec.rb b/spec/unit/recipes/interval_spec.rb new file mode 100644 index 00000000..674dfd37 --- /dev/null +++ b/spec/unit/recipes/interval_spec.rb @@ -0,0 +1,21 @@ +# encoding: utf-8 +# +# Cookbook Name:: audit +# Spec:: default +# +# Copyright (c) 2016 The Authors, All Rights Reserved. + +require 'spec_helper' + +describe 'audit::interval' do + context 'When all attributes are default, on an unspecified platform' do + let(:chef_run) do + runner = ChefSpec::ServerRunner.new + runner.converge(described_recipe) + end + + it 'converges successfully' do + expect { chef_run }.to_not raise_error + end + end +end