def create_docker_image(self, name): """ Create docker image :param name: image's name :return: paclair.docker.DockerImage """ matcher = self._pattern.match(name) if not matcher: raise ResourceNotFoundException("Incorrect image name: {}".format(name)) # Base docker image if matcher.group("domain") is None: return DockerImage("library/" + matcher.group("name"), self.__docker_hub, tag=matcher.group("tag") or 'latest') domain_regex_matcher = self._domain_pattern.search(matcher.group("domain") or "") # Repo docker if domain_regex_matcher is None: return DockerImage("{}/{}".format(matcher.group("domain"), matcher.group("name")), self.__docker_hub, tag=matcher.group("tag") or 'latest') # Find the registry repo = "" if domain_regex_matcher.group("domain") in self.__registries: registry = self.__registries[domain_regex_matcher.group("domain")] repo = domain_regex_matcher.group("repository") or "" elif matcher.group("domain") in self.__registries: registry = self.__registries[matcher.group("domain")] else: registry = DockerRegistry(matcher.group("domain")) return DockerImage(matcher.group("name"), registry, repo, tag=matcher.group("tag") or 'latest')
def push(self, name): rootfs_path = "{}/{}".format(self.base_url, name) result = requests.head(rootfs_path, verify=self.verify) if result.status_code != requests.codes.ok: raise ResourceNotFoundException("{} not found".format(name)) data = self.clair.to_clair_post_data(name, rootfs_path, self.clair_format) self.clair.post_layer(data)
def create_ancestry(self, name): path = "{}/{}".format(self.base_url, name) result = requests.head(path, verify=self.verify) if result.status_code != requests.codes.ok: raise ResourceNotFoundException("{} not found".format(name)) name = self._clean_name(name) return GenericAncestry(self._clean_name(name), self.clair_format, [Layer(name, name, path)])
def push(self, name): # get ID search = { "size": 1, "sort": { '@timestamp': "desc" }, "_source": False, "query": { 'match_phrase': { 'hostname': name } } } result = self._es.search(index=self.index, doc_type=self.doc_type, body=search)['hits'] # no result if result['total'] == 0: raise ResourceNotFoundException("{} not found".format(name)) self.logger.debug( "Remove layer {} from Clair's Database.".format(name)) try: self.delete(name) except ResourceNotFoundException: self.logger.debug( "Layer {} not yet in Clair's Database.".format(name)) id_name = result['hits'][0]['_id'] path = self.__SOURCE_URL.format( self._es.transport.get_connection().host, self.index, self.doc_type, id_name) # Authentication auth = self._es.transport.get_connection().session.auth if auth is not None: digest = "{}:{}".format(*auth) digest = base64.b64encode(digest.encode("utf-8")) headers = { 'Headers': { 'Authorization': 'Basic {}'.format(digest.decode('utf-8')) } } data = self.clair.to_clair_post_data(name, path, self.clair_format, **headers) else: data = self.clair.to_clair_post_data(name, path, self.clair_format) self.clair.post_layer(data)
def _request(self, method, uri, **kwargs): """ Execute http method on uri :param method: http verb :param uri: uri to request :param kwargs: other params :return : server's response """ url = self.url + uri self.logger.debug("Requesting {} on {}".format(method, url)) response = requests.request(method, url, verify=self.verify, **kwargs) try: response.raise_for_status() except requests.exceptions.HTTPError: self.logger.error("Bad http code {} requesting Clair".format( response.status_code)) if response.reason == "Not Found": raise ResourceNotFoundException("Resource not found") raise ClairConnectionError(response) return response
def create_ancestry(self, name): # get ID search = { "size": 1, "sort": { '@timestamp': "desc" }, "_source": False, "query": { 'match_phrase': { 'hostname': name } } } result = self._es.search(index=self.index, doc_type=self.doc_type, body=search)['hits'] # no result if result['total'] == 0: raise ResourceNotFoundException("{} not found".format(name)) id_name = result['hits'][0]['_id'] path = self.__SOURCE_URL.format( self._es.transport.get_connection().host, self.index, self.doc_type, id_name) # Authentication auth = self._es.transport.get_connection().session.auth headers = None if auth is not None: digest = "{}:{}".format(*auth) digest = base64.b64encode(digest.encode("utf-8")) headers = { 'Authorization': 'Basic {}'.format(digest.decode('utf-8')) } return GenericAncestry(name, self.clair_format, [Layer(name, name, path, headers)])