Skip to content

Instantly share code, notes, and snippets.

@sbates
Last active October 5, 2017 14:02
Show Gist options
  • Save sbates/5515021 to your computer and use it in GitHub Desktop.
Save sbates/5515021 to your computer and use it in GitHub Desktop.
a pass at an artifactory resource/provider
require 'chef/provider'
require 'restclient'
class Chef
class Provider
class Artifact < Chef::Provider
def load_current_resource
@current_resource = Chef::Resource::Artifact.new(new_resource.name)
art_user = new_resource.user
art_pass = new_resource.password
@auth = "#{art_user}:#{art_pass}"
@api_auth = "https://#{new_resource.run_context.node[:artifactory][:api]}/search/latestVersion?"
@url_auth = "https://#{@auth}@#{new_resource.run_context.node[:artifactory][:url]}"
grp_id = new_resource.group_id.gsub('.','/')
@sub_uri = ::File.join(new_resource.repo, grp_id, new_resource.name, new_resource.version)
end
def action_download_latest
filename = "#{new_resource.name}-#{find_latest}.#{new_resource.filetype}"
url = ::File.join(@url_auth,@sub_uri,filename)
download(url)
end
def action_download_static
filename = "#{new_resource.name}-#{new_resource.version}.#{new_resource.filetype}"
url = ::File.join(@url_auth,@sub_uri,filename)
download(url)
end
# This calls the artifactory api to get the string indicating the latest version of an artifact
def find_latest
search_url = "#{@api_auth}g=#{new_resource.group_id}&a=#{new_resource.name}&v=#{new_resource.version}&repos=#{new_resource.repo}"
Chef::Log.debug("This is the search_url for #{new_resource.name}: #{search_url.inspect}")
call_artifactory(search_url, @auth)
end
# to get the checksum, input the whole artifact url and the type of checksum you want, as a string (sha-256, sha-1, md5)
def get_checksum(art_url,cksum)
cksum_url = [art_url,cksum].join(".")
call_artifactory(cksum_url, @auth)
end
# Once we've made our custom calls to artifactory, we can use the built-in chef resource for remote_file to actually fetch the artifact
def download(remote_file_url)
# construct the filename and destination for remote file
remote_file_name = "#{new_resource.name}-#{new_resource.version}.#{new_resource.filetype}"
remote_file_destination = new_resource.artifact_target || ::File.join(Chef::Config[:file_cache_path], remote_file_name)
# construct the remote_file source
#Chef::Log.debug("Checking remote file source for artifact #{new_resource.name}: #{remote_file_url.inspect}")
sha256_cksum = get_checksum(remote_file_url, "sha256")
Chef::Log.debug("checking sha256 checksum for #{new_resource.name}:#{sha256_cksum.inspect}")
# Use the remote_file resource to go fetch the artifact now that we know the url AND the checksum
f = Chef::Resource::RemoteFile.new(remote_file_destination, run_context)
f.checksum sha256_cksum
f.source remote_file_url
f.run_action :create
f.retries 3
# If the file is new or updated, set this resource to updated so that notifications will happen
new_resource.updated_by_last_action(true) if f.updated_by_last_action?
end
# calls artifactory and returns a value
def call_artifactory(url, auth)
RestClient.proxy = Chef::Config["https_proxy"] unless Chef::Config["https_proxy"].nil?
headers = ({"AUTHORIZATION" => "Basic #{Base64.encode64(auth)}"})
RestClient.get url, headers
end
end
end
end
actions :download_latest, :download_static
attribute :artifact, :kind_of => String, :required => true, :name_attribute => true
attribute :version, :kind_of => String, :required => true
attribute :repo, :kind_of => String, :required => true
attribute :filetype, :kind_of => String, :required => true, :default => "war"
attribute :group_id, :kind_of => String, :required => true
attribute :artifact_target, :kind_of => String
def initialize(*args)
super
@action = :create
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment