Skip to content

Instantly share code, notes, and snippets.

@lusis
Last active April 9, 2019 19:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save lusis/24e44858990988c686b309c4c170c8b3 to your computer and use it in GitHub Desktop.
Save lusis/24e44858990988c686b309c4c170c8b3 to your computer and use it in GitHub Desktop.
Artifactory Yum plugin (based on this s3 plugin - https://github.com/jbraeuer/yum-s3-plugin/blob/master/s3.py)
# place in /etc/yum/pluginconf.d/artifactory.conf
[main]
enabled=1
"""
Yum plugin for Artifactory access.
This plugin provides access to a protected Artifactory Yum Repo
On CentOS this file goes into /usr/lib/yum-plugins/artifactory.py
You will also need two configuration files. See artifactory.conf and artifactorytest.repo for
examples on how to deploy those.
"""
# Copyright 2016, John E Vincent
#
# 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.
import logging
import os
import sys
import urllib
from yum.plugins import TYPE_CORE
from yum.yumRepo import YumRepository
from yum import config
from yum import logginglevels
import yum.Errors
def interactive_notify(msg):
if sys.stdout.isatty():
print msg
def createUrllibGrabber():
"""
Fetch files from artifactory.
"""
import os
import sys
import urllib2
import base64
class UrllibGrabber:
@classmethod
def artifactorysign(cls, request, user, password, apikey=None):
host = request.get_host()
if apikey:
request.add_header('X-JFrog-Art-Api', apikey)
else:
base64string = base64.encodestring('%s:%s' % (user, password)).replace('\n','')
request.add_header("Authorization", "Basic %s" % base64string)
def __init__(self, user, password, apikey, baseurl ):
try: baseurl = baseurl[0]
except: pass
if baseurl[:-1] != '/':
baseurl = baseurl + '/'
self.baseurl = baseurl
self.user = user
self.password = password
self.apikey = apikey
def _request(self,url):
req = urllib2.Request("%s%s" % (self.baseurl, url))
UrllibGrabber.artifactorysign(req, self.user, self.password, self.apikey )
return req
def urlgrab(self, url, filename=None, **kwargs):
"""urlgrab(url) copy the file to the local filesystem"""
req = self._request(url)
out = open(filename, 'w+')
resp = urllib2.urlopen(req)
buff = resp.read(8192)
while buff:
out.write(buff)
buff = resp.read(8192)
return filename
# zzz - does this return a value or something?
def urlopen(self, url, **kwargs):
"""urlopen(url) open the remote file and return a file object"""
return urllib2.urlopen( self._request(url) )
def urlread(self, url, limit=None, **kwargs):
"""urlread(url) return the contents of the file as a string"""
return urllib2.urlopen( self._request(url) ).read()
return UrllibGrabber
def createGrabber():
logger = logging.getLogger("yum.verbose.main")
grabber = createUrllibGrabber()
logger.debug("Using ArtifactoryGrabber")
return grabber
ArtifactoryGrabber = createGrabber()
class ArtifactoryRepo(YumRepository):
"""
Repository object for Artifactory.
"""
def __init__(self, repoid):
YumRepository.__init__(self, repoid)
self.enable()
self.grabber = None
def setupGrab(self):
YumRepository.setupGrab(self)
self.grabber = ArtifactoryGrabber(self.artifactory_user, self.artifactory_password, self.artifactory_apikey)
def _getgrabfunc(self): raise Exception("get grabfunc!")
def _getgrab(self):
if not self.grabber:
self.grabber = ArtifactoryGrabber(self.artifactory_user, self.artifactory_password, self.artifactory_apikey, baseurl=self.baseurl )
return self.grabber
grabfunc = property(lambda self: self._getgrabfunc())
grab = property(lambda self: self._getgrab())
__revision__ = "1.0.0"
requires_api_version = '2.5'
plugin_type = TYPE_CORE
def config_hook(conduit):
logger = logging.getLogger("yum.verbose.main")
config.RepoConf.artifactory_enabled = config.BoolOption(False)
config.RepoConf.artifactory_user = config.Option() or conduit.confString('main', 'artifactory_user')
config.RepoConf.artifactory_password = config.Option() or conduit.confString('main', 'artifactory_password')
config.RepoConf.artifactory_apikey = config.Option() or conduit.confString('main', 'artifactory_apikey')
def prereposetup_hook(conduit):
"""
Plugin initialization hook. Setup the Artifactory repositories.
"""
repos = conduit.getRepos()
conf = conduit.getConf()
cachedir = conduit.getConf().cachedir
for key,repo in repos.repos.iteritems():
if isinstance(repo, YumRepository) and repo.artifactory_enabled and repo.isEnabled():
new_repo = ArtifactoryRepo(key)
new_repo.name = repo.name
new_repo.baseurl = repo.baseurl
new_repo.mirrorlist = repo.mirrorlist
new_repo.basecachedir = repo.basecachedir
new_repo.gpgcheck = repo.gpgcheck
new_repo.gpgkey = repo.gpgkey
new_repo.proxy = repo.proxy
new_repo.enablegroups = repo.enablegroups
new_repo.artifactory_user = repo.artifactory_user
new_repo.artifactory_password = repo.artifactory_password
new_repo.artifactory_apikey= repo.artifactory_apikey
new_repo.metadata_expire = repo.metadata_expire
if hasattr(repo, 'priority'):
new_repo.priority = repo.priority
if hasattr(repo, 'base_persistdir'):
new_repo.base_persistdir = repo.base_persistdir
repos.delete(repo.id)
repos.add(new_repo)
[somerepo]
name=somerepo
baseurl=https://artifactory.mydomain.com/artifactory/yum-local/$releasever/$basearch
enabled=1
artifactory_enabled=1
# pick either username/password auth OR apikey auth. Apikey wins out in case of all options defined
#artifactory_user=foo
#artifactory_password=bar
#artifactory_apikey=XXXXXXXXX
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment