Class: ChefDK::Policyfile::Uploader

Inherits:
Object
  • Object
show all
Defined in:
lib/chef-dk/policyfile/uploader.rb

Defined Under Namespace

Classes: LockedCookbookForUpload

Constant Summary collapse

COMPAT_MODE_DATA_BAG_NAME =
"policyfiles".freeze

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(policyfile_lock, policy_group, ui: nil, http_client: nil) ⇒ Uploader

Returns a new instance of Uploader.



37
38
39
40
41
42
43
44
# File 'lib/chef-dk/policyfile/uploader.rb', line 37

def initialize(policyfile_lock, policy_group, ui: nil, http_client: nil)
  @policyfile_lock = policyfile_lock
  @policy_group = policy_group
  @http_client = http_client
  @ui = ui || UI.null

  @cookbook_versions_for_policy = nil
end

Instance Attribute Details

#http_clientObject (readonly)

Returns the value of attribute http_client.



34
35
36
# File 'lib/chef-dk/policyfile/uploader.rb', line 34

def http_client
  @http_client
end

#policy_groupObject (readonly)

Returns the value of attribute policy_group.



33
34
35
# File 'lib/chef-dk/policyfile/uploader.rb', line 33

def policy_group
  @policy_group
end

#policyfile_lockObject (readonly)

Returns the value of attribute policyfile_lock.



32
33
34
# File 'lib/chef-dk/policyfile/uploader.rb', line 32

def policyfile_lock
  @policyfile_lock
end

#uiObject (readonly)

Returns the value of attribute ui.



35
36
37
# File 'lib/chef-dk/policyfile/uploader.rb', line 35

def ui
  @ui
end

Instance Method Details

#cookbook_versions_for_policyObject

An Array of Chef::CookbookVersion objects representing the full set that the policyfile lock requires.



108
109
110
111
112
113
114
115
# File 'lib/chef-dk/policyfile/uploader.rb', line 108

def cookbook_versions_for_policy
  return @cookbook_versions_for_policy if @cookbook_versions_for_policy
  policyfile_lock.validate_cookbooks!
  @cookbook_versions_for_policy = policyfile_lock.cookbook_locks.map do |name, lock|
    cb = ReadCookbookForCompatModeUpload.load(name, lock.dotted_decimal_identifier, lock.cookbook_path)
    LockedCookbookForUpload.new(cb, lock)
  end
end

#cookbook_versions_to_uploadObject



86
87
88
89
90
91
92
# File 'lib/chef-dk/policyfile/uploader.rb', line 86

def cookbook_versions_to_upload
  cookbook_versions_for_policy.inject([]) do |versions_to_upload, cookbook_with_lock|
    cb = cookbook_with_lock.cookbook
    versions_to_upload << cb unless remote_already_has_cookbook?(cb)
    versions_to_upload
  end
end

#data_bag_createObject



54
55
56
57
58
# File 'lib/chef-dk/policyfile/uploader.rb', line 54

def data_bag_create
  http_client.post("data", {"name" => COMPAT_MODE_DATA_BAG_NAME})
rescue Net::HTTPServerException => e
  raise e unless e.response.code == "409"
end

#data_bag_item_createObject



60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/chef-dk/policyfile/uploader.rb', line 60

def data_bag_item_create
  policy_id = "#{policyfile_lock.name}-#{policy_group}"
  lock_data = policyfile_lock.to_lock.dup

  lock_data["id"] = policy_id

  data_item = {
    "id" => policy_id,
    "name" => "data_bag_item_#{COMPAT_MODE_DATA_BAG_NAME}_#{policy_id}",
    "data_bag" => COMPAT_MODE_DATA_BAG_NAME,
    "raw_data" => lock_data,
    # we'd prefer to leave this out, but the "compatibility mode"
    # implementation in chef-client relies on magical class inflation
    "json_class" => "Chef::DataBagItem"
  }

  upload_lockfile_as_data_bag_item(policy_id, data_item)
  ui.msg("Policy uploaded as data bag item #{COMPAT_MODE_DATA_BAG_NAME}/#{policy_id}")
  true
end

#existing_cookbook_on_remoteObject



102
103
104
# File 'lib/chef-dk/policyfile/uploader.rb', line 102

def existing_cookbook_on_remote
  @existing_cookbook_on_remote ||= http_client.get('cookbooks?num_versions=all')
end

#remote_already_has_cookbook?(cookbook) ⇒ Boolean

Returns:

  • (Boolean)


94
95
96
97
98
99
100
# File 'lib/chef-dk/policyfile/uploader.rb', line 94

def remote_already_has_cookbook?(cookbook)
  return false unless existing_cookbook_on_remote.key?(cookbook.name.to_s)

  existing_cookbook_on_remote[cookbook.name.to_s]["versions"].any? do |cookbook_info|
    cookbook_info["version"] == cookbook.version
  end
end

#uploadObject



46
47
48
49
50
51
52
# File 'lib/chef-dk/policyfile/uploader.rb', line 46

def upload
  ui.msg("WARN: Uploading policy to policy group #{policy_group} in compatibility mode")

  upload_cookbooks
  data_bag_create
  data_bag_item_create
end

#uploaderObject



81
82
83
84
# File 'lib/chef-dk/policyfile/uploader.rb', line 81

def uploader
  # TODO: uploader runs cookbook validation; we want to do this at a different time.
  @uploader ||= Chef::CookbookUploader.new(cookbook_versions_to_upload, :rest => http_client)
end