class ChefZero::ChefData::DataNormalizer

Constants

COOKBOOK_SEGMENTS

Public Class Methods

normalize_acls(acls) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 11
def self.normalize_acls(acls)
  ChefData::DefaultCreator::PERMISSIONS.each do |perm|
    acls[perm] ||= {}
    acls[perm]["groups"] ||= []
    if acls[perm].key? "users"
      # When clients and users are split, their combined list
      # is the final list of actors that a subsequent GET will
      # provide. Each list is guaranteed to be unique, but the
      # combined list is not.
      acls[perm]["actors"] = acls[perm]["clients"].uniq +
        acls[perm]["users"].uniq
    else
      # this gets doubled sometimes, for reasons.
      (acls[perm]["actors"] ||= []).uniq!
    end
  end
  acls
end
normalize_client(client, name, orgname = nil) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 30
def self.normalize_client(client, name, orgname = nil)
  client["name"] ||= name
  client["clientname"] ||= name
  client["admin"] = !!client["admin"] if client.key?("admin")
  client["public_key"] = PUBLIC_KEY unless client.key?("public_key")
  client["orgname"] ||= orgname
  client["validator"] ||= false
  client["validator"] = !!client["validator"]
  client["json_class"] ||= "Chef::ApiClient"
  client["chef_type"] ||= "client"
  client
end
normalize_container(container, name) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 43
def self.normalize_container(container, name)
  container.delete("id")
  container["containername"] = name
  container["containerpath"] = name
  container
end
normalize_cookbook(endpoint, org_prefix, cookbook, name, version, base_uri, method, is_cookbook_artifact = false, api_version: 2) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 96
def self.normalize_cookbook(endpoint, org_prefix, cookbook, name, version, base_uri, method,
  is_cookbook_artifact = false, api_version: 2)
  # TODO I feel dirty
  if method == "PUT" && api_version < 2
    cookbook["all_files"] = cookbook.delete(["root_files"]) { [] }
    COOKBOOK_SEGMENTS.each do |segment|
      next unless cookbook.key? segment

      cookbook[segment].each do |file|
        file["name"] = "#{segment}/#{file["name"]}"
        cookbook["all_files"] << file
      end
      cookbook.delete(segment)
    end
  elsif method != "PUT"
    if cookbook.key? "all_files"
      cookbook["all_files"].each do |file|
        if file.is_a?(Hash) && file.key?("checksum")
          file["url"] ||= endpoint.build_uri(base_uri, org_prefix + ["file_store", "checksums", file["checksum"]])
        end
      end

      # down convert to old style manifest, ensuring we don't send all_files on the wire and that we correctly divine segments
      # any file that's not in an old segment is just dropped on the floor.
      if api_version < 2

        # the spec appears to think we should send empty arrays for each segment, so let's do that
        COOKBOOK_SEGMENTS.each { |seg| cookbook[seg] ||= [] }

        cookbook["all_files"].each do |file|
          segment, name = file["name"].split("/")

          # root_files have no segment prepended
          if name.nil?
            name = segment
            segment = "root_files"
          end

          file.delete("full_path")
          next unless COOKBOOK_SEGMENTS.include? segment

          file["name"] = name
          cookbook[segment] << file
        end
        cookbook.delete("all_files")
      end
    end

    cookbook["name"] ||= "#{name}-#{version}"
    # TODO it feels wrong, but the real chef server doesn't expand 'version', so we don't either.

    cookbook["frozen?"] ||= false
    cookbook["metadata"] ||= {}
    cookbook["metadata"]["version"] ||= version

    # defaults set by the client and not the Server:
    # metadata[name, description, maintainer, maintainer_email, license]

    cookbook["metadata"]["long_description"] ||= ""
    cookbook["metadata"]["dependencies"] ||= {}
    cookbook["metadata"]["attributes"] ||= {}
    cookbook["metadata"]["recipes"] ||= {}
  end

  if is_cookbook_artifact
    cookbook.delete("json_class")
  else
    cookbook["cookbook_name"] ||= name
    cookbook["json_class"] ||= "Chef::CookbookVersion"
  end

  cookbook["chef_type"] ||= "cookbook_version"
  if method == "MIN"
    cookbook["metadata"].delete("attributes")
    cookbook["metadata"].delete("long_description")
  end
  cookbook
end
normalize_data_bag_item(data_bag_item, data_bag_name, id, method) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 70
def self.normalize_data_bag_item(data_bag_item, data_bag_name, id, method)
  if method == "DELETE"
    # TODO SERIOUSLY, WHO DOES THIS MANY EXCEPTIONS IN THEIR INTERFACE
    unless data_bag_item["json_class"] == "Chef::DataBagItem" && data_bag_item["raw_data"]
      data_bag_item["id"] ||= id
      data_bag_item = { "raw_data" => data_bag_item }
      data_bag_item["chef_type"] ||= "data_bag_item"
      data_bag_item["json_class"] ||= "Chef::DataBagItem"
      data_bag_item["data_bag"] ||= data_bag_name
      data_bag_item["name"] ||= "data_bag_item_#{data_bag_name}_#{id}"
    end
  else
    # If it's not already wrapped with raw_data, wrap it.
    if data_bag_item["json_class"] == "Chef::DataBagItem" && data_bag_item["raw_data"]
      data_bag_item = data_bag_item["raw_data"]
    end
    # Argh.  We don't do this on GET, but we do on PUT and POST????
    if %w{PUT POST}.include?(method)
      data_bag_item["chef_type"] ||= "data_bag_item"
      data_bag_item["data_bag"] ||= data_bag_name
    end
    data_bag_item["id"] ||= id
  end
  data_bag_item
end
normalize_environment(environment, name) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 175
def self.normalize_environment(environment, name)
  environment["name"] ||= name
  environment["description"] ||= ""
  environment["cookbook_versions"] ||= {}
  environment["json_class"] ||= "Chef::Environment"
  environment["chef_type"] ||= "environment"
  environment["default_attributes"] ||= {}
  environment["override_attributes"] ||= {}
  environment
end
normalize_group(group, name, orgname) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 186
def self.normalize_group(group, name, orgname)
  group.delete("id")
  if group["actors"].is_a?(Hash)
    group["users"] ||= group["actors"]["users"]
    group["clients"] ||= group["actors"]["clients"]
    group["groups"] ||= group["actors"]["groups"]
    group["actors"] = nil
  end
  group["users"] ||= []
  group["clients"] ||= []
  group["actors"] ||= (group["clients"] + group["users"])
  group["groups"] ||= []
  group["orgname"] ||= orgname if orgname
  group["name"] ||= name
  group["groupname"] ||= name

  group["users"].uniq!
  group["clients"].uniq!
  group["actors"].uniq!
  group["groups"].uniq!
  group
end
normalize_node(node, name) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 209
def self.normalize_node(node, name)
  node["name"] ||= name
  node["json_class"] ||= "Chef::Node"
  node["chef_type"] ||= "node"
  node["chef_environment"] ||= "_default"
  node["override"] ||= {}
  node["normal"] ||= { "tags" => [] }
  node["default"] ||= {}
  node["automatic"] ||= {}
  node["run_list"] ||= []
  node["run_list"] = normalize_run_list(node["run_list"])
  node
end
normalize_organization(org, name) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 237
def self.normalize_organization(org, name)
  org["name"] ||= name
  org["full_name"] ||= name
  org["org_type"] ||= "Business"
  org["clientname"] ||= "#{name}-validator"
  org["billing_plan"] ||= "platform-free"
  org
end
normalize_policy(policy, name, revision) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 223
def self.normalize_policy(policy, name, revision)
  policy["name"] ||= name
  policy["revision_id"] ||= revision
  policy["run_list"] ||= []
  policy["cookbook_locks"] ||= {}
  policy
end
normalize_policy_group(policy_group, name) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 231
def self.normalize_policy_group(policy_group, name)
  policy_group[name] ||= "name"
  policy_group["policies"] ||= {}
  policy_group
end
normalize_role(role, name) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 246
def self.normalize_role(role, name)
  role["name"] ||= name
  role["description"] ||= ""
  role["json_class"] ||= "Chef::Role"
  role["chef_type"] ||= "role"
  role["default_attributes"] ||= {}
  role["override_attributes"] ||= {}
  role["run_list"] ||= []
  role["run_list"] = normalize_run_list(role["run_list"])
  role["env_run_lists"] ||= {}
  role["env_run_lists"].each_pair do |env, run_list|
    role["env_run_lists"][env] = normalize_run_list(run_list)
  end
  role
end
normalize_run_list(run_list) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 262
def self.normalize_run_list(run_list)
  run_list.map do |item|
    case item
    when /^recipe\[.*\]$/
      item # explicit recipe
    when /^role\[.*\]$/
      item # explicit role
    else
      "recipe[#{item}]"
    end
  end.uniq
end
normalize_user(user, name, identity_keys, osc_compat, method = nil) click to toggle source
# File lib/chef_zero/chef_data/data_normalizer.rb, line 50
def self.normalize_user(user, name, identity_keys, osc_compat, method = nil)
  user[identity_keys.first] ||= name
  user["public_key"] = PUBLIC_KEY unless user.key?("public_key")
  user["admin"] ||= false
  user["admin"] = !!user["admin"]
  user["openid"] ||= nil
  unless osc_compat
    if method == "GET"
      user.delete("admin")
      user.delete("password")
      user.delete("openid")
    end
    user["email"] ||= nil
    user["first_name"] ||= nil
    user["last_name"] ||= nil
    user["display_name"] ||= nil
  end
  user
end