Chef_Processors/ChefDirectory.py (195 lines of code) (raw):

#!/usr/bin/python # -*- coding: utf-8 -*- # # Copyright (c) Facebook, Inc. and its affiliates. # # This source code is licensed under the BSD-style license found in the # LICENSE file in the root directory of this source tree.# """See docstring for ChefDirectory class.""" from __future__ import absolute_import from autopkglib import Processor __all__ = ["ChefDirectory"] class ChefDirectory(Processor): description = ( "Produces a directory Chef block. See " "https://docs.chef.io/resource_directory.html." ) input_variables = { "resource_name": { "required": True, "description": ( "Name for the resource. This can be a single " "string or an array of strings. If an array is " "provided, the first item in the array will be the " "resource name and the rest will be turned " "into an array." ), }, "directory_resource_array": { "required": False, "description": "Does the resource_name represent an array variable?", }, "directory_action": { "required": False, "description": "Resource action. See documentation.", }, "directory_group": { "required": False, "description": "Use to configure permissions for directories.", }, "directory_ignore_failure": { "required": False, "description": ( "Continue running a recipe if a resource fails for any reason." ), }, "directory_inherits": { "required": False, "description": ( "Windows only. Whether a file inherits rights from " "its parent directory." ), }, "directory_mode": { "required": False, "description": ( "A quoted 3-5 character string that defines the octal mode." ), }, "directory_notifies": { "required": False, "description": ( "Which resource takes action when this resource's state changes." ), }, "directory_owner": { "required": False, "description": "Use to configure permissions for directories.", }, "directory_path": { "required": False, "description": "The path to the directory.", }, "directory_provider": { "required": False, "description": "Optional. Explicitly specify a provider.", }, "directory_recursive": { "required": False, "description": "Create or delete directories recursively.", }, "directory_retries": { "required": False, "description": ( "The number of times to catch exceptions and retry the resource." ), }, "directory_retry_delay": { "required": False, "description": "The retry delay (in seconds).", }, "directory_rights": { "required": False, "description": ( "Microsoft Windows only. The permissions for users and " "groups in a Microsoft Windows environment." ), }, "directory_subscribes": { "required": False, "description": ( "Specify that this resource is to listen to another " "resource, and then take action when that resource's " "state changes.." ), }, "directory_only_if": { "required": False, "description": "only_if guard phrase.", }, "directory_not_if": {"required": False, "description": "not_if guard phrase."}, "directory_extra_indentation": { "required": False, "description": "Indent this block. Defaults to empty.", }, "directory_indentation_end": { "required": False, "description": "Should this end an indented section? Defaults to empty.", }, } output_variables = {"chef_block": {"description": "Chef block."}} __doc__ = description def main(self): # chef block variables prefix = "directory_" block_name = "directory" # formatting variables extra_formatting = "" end_text = "end\n" self.env["chef_block"] = "" each_do_beginning = "[\n" each_do_end = ".each do |item|\n" self.env["chef_block"] = each_do_beginning name = "item" notif_text = "not_if" onlyif_text = "only_if" indent_block = "" # Should this block be indented? if self.env.get("%sextra_indentation" % prefix): self.output("Adding indentation.") indent_block = " " end_text = " " + end_text extra_formatting = " " # Should this end an indented block? if self.env.get("%sindentation_end" % prefix): end_text = end_text + "end\n" # Check to see if only one item was passed if len(self.env["resource_name"].split(",")) == 1: if self.env.get("%sresource_array" % prefix): # it's a node variable representating an array self.env["chef_block"] = ( indent_block + block_name + " " + self.env["resource_name"] + each_do_end ) else: self.env["chef_block"] = ( indent_block + block_name + " " + self.env["resource_name"] + " do\n" ) else: for resource_name in self.env["resource_name"].split(","): self.env["chef_block"] += " %s,\n" % resource_name self.env["chef_block"] += "]" + each_do_end # Remove trailing comma self.env["chef_block"] = self.env["chef_block"].replace(",\n]", "\n]") self.env["chef_block"] += "%s %s do\n" % (block_name, name) # Insert an extra tab before everything extra_formatting = " " end_text = indent_block + "end\n\n" input_list = sorted(self.input_variables.keys()) # Start the block # Remove the indentation keys input_list.remove("%sextra_indentation" % prefix) input_list.remove("%sindentation_end" % prefix) # Place not_if guards first if self.env.get("%snot_if" % prefix): self.env["chef_block"] += "%s %s %s\n" % ( extra_formatting, notif_text, self.env["%snot_if" % prefix], ) input_list.remove("%snot_if" % prefix) # Place only_if guards next if self.env.get("%sonly_if" % prefix): self.env["chef_block"] += "%s %s %s\n" % ( extra_formatting, onlyif_text, self.env["%sonly_if" % prefix], ) input_list.remove("%sonly_if" % prefix) # Remove the special keys input_list.remove("%sresource_array" % prefix) input_list.remove("resource_name") # Loop through all remaining keys for key in input_list: if self.env.get(key, ""): key_text = "%s" % key.replace("%s" % prefix, "") self.env["chef_block"] += "%s %s %s\n" % ( extra_formatting, key_text, self.env[key], ) # Clear out the key so it doesn't poison future runs self.env[key] = "" # end it self.env["chef_block"] += end_text + "\n" self.output("Chef block:\n%s" % self.env["chef_block"]) # Clean up the keys that weren't iterated through self.env["%sextra_indentation" % prefix] = "" self.env["%sindentation_end" % prefix] = "" self.env["%snot_if" % prefix] = "" self.env["%sonly_if" % prefix] = "" if __name__ == "__main__": PROCESSOR = ChefDirectory() PROCESSOR.execute_shell()