lib/chef-cli/policyfile_services/clean_policies.rb
# # Copyright:: 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_relative "../exceptions" require_relative "../service_exceptions" require_relative "../policyfile/lister" module ChefCLI module PolicyfileServices class CleanPolicies Orphan = Struct.new(:policy_name, :revision_id) attr_reader :chef_config attr_reader :ui def initialize(config: nil, ui: nil) @chef_config = config @ui = ui end def run revisions_to_remove = orphaned_policies if revisions_to_remove.empty? ui.err("No policy revisions deleted") return true end results = revisions_to_remove.map do |policy| [ remove_policy(policy), policy ] end failures = results.select { |result, _policy| result.is_a?(Exception) } unless failures.empty? details = failures.map do |result, policy| "- #{policy.policy_name} (#{policy.revision_id}): #{result.class} #{result}" end message = "Failed to delete some policy revisions:\n" + details.join("\n") + "\n" raise PolicyfileCleanError.new(message, MultipleErrors.new("multiple errors")) end true end def orphaned_policies policy_lister.policies_by_name.keys.inject([]) do |orphans, policy_name| orphans + policy_lister.orphaned_revisions(policy_name).map do |revision_id| Orphan.new(policy_name, revision_id) end end rescue => e raise PolicyfileCleanError.new("Failed to list policies for cleaning.", e) end def policy_lister @policy_lister ||= Policyfile::Lister.new(config: chef_config) end def http_client @http_client ||= Chef::ServerAPI.new(chef_config.chef_server_url, signing_key_filename: chef_config.client_key, client_name: chef_config.node_name) end private def remove_policy(policy) ui.msg("DELETE #{policy.policy_name} #{policy.revision_id}") http_client.delete("/policies/#{policy.policy_name}/revisions/#{policy.revision_id}") :ok rescue => e e end end end end