class PkgFullMatchTrigger(BaseTrigger): __lifecycle_state__ = LifecycleStates.deprecated __trigger_name__ = 'npmpkgfullmatch' __description__ = 'triggers if the evaluated image has an NPM package installed that matches one in the list given as a param (package_name|vers)' blacklist_names = NameVersionStringListParameter(name='blacklist_npmfullmatch', example_str='json|1.0.1,datetime|1.1.1', description='List of name|version matches for full package match on blacklist') def evaluate(self, image_obj, context): """ Fire for any npm that is on the blacklist with a full name + version match :param image_obj: :param context: :return: """ npms = image_obj.npms if not npms: return pkgs = context.data.get(NPM_LISTING_KEY) if not pkgs: return match_versions = self.blacklist_names.value() if self.blacklist_names.value() else {} for pkg, vers in list(match_versions.items()): try: if pkg in pkgs and vers in pkgs.get(pkg, []): self._fire(msg='NPMPKGFULLMATCH Package is blacklisted: '+pkg+"-"+vers) except Exception as e: continue
class PkgFullMatchTrigger(BaseTrigger): __lifecycle_state__ = LifecycleStates.deprecated __trigger_name__ = 'gempkgfullmatch' __description__ = 'triggers if the evaluated image has an GEM package installed that matches one in the list given as a param (package_name|vers)' fullmatch_blacklist = NameVersionStringListParameter( name='blacklist_gemfullmatch', example_str='time_diff|1.0.1,json|1.2', description= 'List of name|version entries that are matched exactly for blacklist', is_required=False) def evaluate(self, image_obj, context): """ Fire for any gem that is on the blacklist with a full name + version match :param image_obj: :param context: :return: """ gems = image_obj.gems if not gems: return pkgs = context.data.get(GEM_LIST_KEY) if not pkgs: return blacklist_pkgs = self.fullmatch_blacklist.value() if blacklist_pkgs is None: blacklist_pkgs = {} for pkg, vers in blacklist_pkgs.items(): if pkg in pkgs and vers in pkgs.get(pkg, []): self._fire(msg='GEMPKGFULLMATCH Package is blacklisted: ' + pkg + "-" + vers)
class FullMatchTrigger(BaseTrigger): __trigger_name__ = 'pkgfullmatch' __description__ = 'triggers if the evaluated image has a package installed that matches one in the list given as a param (package_name|vers)' fullmatch_blacklist = NameVersionStringListParameter( name='blacklist_fullmatch', description='List of package name|version pairs for exact match') def evaluate(self, image_obj, context): pkgs = self.fullmatch_blacklist.value( ) if self.fullmatch_blacklist.value() else [] for pkg, vers in pkgs.items(): try: matches = image_obj.packages.filter( ImagePackage.name == pkg, ImagePackage.version == vers) for m in matches: self._fire(msg='PKGFULLMATCH Package is blacklisted: ' + m.name + "-" + m.version) except Exception as e: log.exception('Error filtering packages for full match') pass
class PkgNotPresentTrigger(BaseTrigger): __lifecycle_state__ = LifecycleStates.deprecated __trigger_name__ = 'pkgnotpresent' __description__ = 'triggers if the package(s) specified in the params are not installed in the container image. The parameters specify different types of matches.', pkg_full_match = NameVersionStringListParameter( name='pkgfullmatch', description= 'Match these values on both name and exact version. Entries are comma-delimited with a pipe between pkg name and version', example_str='pkg1|version1,pkg2|version2', is_required=False) pkg_name_match = CommaDelimitedStringListParameter( name='pkgnamematch', description='List of names to match', example_str='wget,curl,libssl', is_required=False) pkg_version_match = NameVersionStringListParameter( name='pkgversmatch', description= 'Names and versions to do a minimum-version check on. Any package in the list with a version less than the specified version will cause the trigger to fire', example_str='wget|1.19.3,curl|7.55.1', is_required=False) def evaluate(self, image_obj, context): fullmatch = self.pkg_full_match.value(default_if_none={}) namematch = self.pkg_name_match.value(default_if_none=[]) vermatch = self.pkg_version_match.value(default_if_none={}) names = set(fullmatch.keys()).union(set(namematch)).union( set(vermatch.keys())) if not names: return # Filter is possible since the lazy='dynamic' is set on the packages relationship in Image. for img_pkg in image_obj.packages.filter( ImagePackage.name.in_(names)).all(): if img_pkg.name in fullmatch: if img_pkg.fullversion != fullmatch.get(img_pkg.name): # Found but not right version self._fire( msg="PKGNOTPRESENT input package (" + str(img_pkg.name) + ") is present (" + str(img_pkg.fullversion) + "), but not at the version specified in policy (" + str(fullmatch[img_pkg.name]) + ")") fullmatch.pop( img_pkg.name ) # Assume only one version of a given package name is installed else: # Remove it from the list fullmatch.pop(img_pkg.name) # Name match is sufficient if img_pkg.name in namematch: namematch.remove(img_pkg.name) if img_pkg.name in vermatch: if img_pkg.fullversion != vermatch[img_pkg.name]: # Check if version is less than param value if compare_package_versions( img_pkg.distro_namespace_meta.flavor, img_pkg.name, img_pkg.version, img_pkg.name, vermatch[img_pkg.name]) < 0: self._fire( msg="PKGNOTPRESENT input package (" + str(img_pkg.name) + ") is present (" + str(img_pkg.fullversion) + "), but is lower version than what is specified in policy (" + str(vermatch[img_pkg.name]) + ")") vermatch.pop(img_pkg.name) # Any remaining for pkg, version in fullmatch.items(): self._fire(msg="PKGNOTPRESENT input package (" + str(pkg) + "-" + str(version) + ") is not present in container image") for pkg, version in vermatch.items(): self._fire(msg="PKGNOTPRESENT input package (" + str(pkg) + "-" + str(version) + ") is not present in container image") for pkg in namematch: self._fire(msg="PKGNOTPRESENT input package (" + str(pkg) + ") is not present in container image")