1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
#
# Author:: Steven Danna (<steve@chef.io>)
# Copyright:: Copyright 2014-2016, Chef Software, Inc
# License:: Apache License, Version 2.0
#
# 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/exceptions"
require "chef/guard_interpreter"
require "chef/mixin/descendants_tracker"
class Chef
class Resource
class File < Chef::Resource
#
# See RFC 027 for a full specification
#
# File verifications allow user-supplied commands a means of
# preventing file resource content deploys. Their intended use
# is to verify the contents of a temporary file before it is
# deployed onto the system.
#
# Similar to not_if and only_if, file verifications can take a
# ruby block, which will be called, or a string, which will be
# executed as a Shell command.
#
# Additonally, Chef or third-party verifications can ship
# "registered verifications" that the user can use by specifying
# a :symbol as the command name.
#
# To create a registered verification, create a class that
# inherits from Chef::Resource::File::Verification and use the
# provides class method to give it name. Registered
# verifications are expected to supply a verify instance method
# that takes 2 arguments.
#
# Example:
# class Chef
# class Resource
# class File::Verification::Foo < Chef::Resource::File::Verification
# provides :noop
# def verify(path, opts)
# #yolo
# true
# end
# end
# end
# end
#
#
class Verification
extend Chef::Mixin::DescendantsTracker
def self.provides(name)
@provides = name
end
def self.provides?(name)
@provides == name
end
def self.lookup(name)
c = descendants.find { |d| d.provides?(name) }
if c.nil?
raise Chef::Exceptions::VerificationNotFound.new "No file verification for #{name} found."
end
c
end
def logger
@parent_resource.logger
end
def initialize(parent_resource, command, opts, &block)
@command, @command_opts = command, opts
@block = block
@parent_resource = parent_resource
end
def verify(path, opts = {})
logger.trace("Running verification[#{self}] on #{path}")
if @block
verify_block(path, opts)
elsif @command.is_a?(Symbol)
verify_registered_verification(path, opts)
elsif @command.is_a?(String)
verify_command(path, opts)
end
end
# opts is currently unused, but included in the API
# to support future extensions
def verify_block(path, opts)
@block.call(path)
end
# We reuse Chef::GuardInterpreter in order to support
# the same set of options that the not_if/only_if blocks do
def verify_command(path, opts)
if @command.include?("%{file}")
raise ArgumentError, "The %{file} expansion for verify commands has been removed. Please use %{path} instead."
end
command = @command % { path: path }
interpreter = Chef::GuardInterpreter.for_resource(@parent_resource, command, @command_opts)
interpreter.evaluate
end
def verify_registered_verification(path, opts)
verification_class = Chef::Resource::File::Verification.lookup(@command)
v = verification_class.new(@parent_resource, @command, @command_opts, &@block)
v.verify(path, opts)
end
def to_s
if @block
"<Proc>"
elsif @command.is_a?(Symbol)
"#{@command.inspect} (#{Chef::Resource::File::Verification.lookup(@command).name})"
elsif @command.is_a?(String)
@command
end
end
end
end
end
end
|