def test_post_ancestry(self, m): """ Test post_ancestry """ self.clair._request = Mock(autospec=True) ancestry = GenericAncestry("ubuntu", "Docker", [ Layer("aaaaa", "hash_aaaaa", "path_aaaaa"), Layer("bbbbb", "hash_bbbbb", "path_bbbbb") ]) expected_json = { 'ancestry_name': 'ubuntu', 'format': 'Docker', 'layers': [{ 'hash': 'hash_aaaaa', 'path': 'path_aaaaa', 'headers': None }, { 'hash': 'hash_bbbbb', 'path': 'path_bbbbb', 'headers': None }] } self.clair.post_ancestry(ancestry) self.clair._request.assert_called_with('POST', '/ancestry', json=expected_json)
def test_post_ancestry(self, m): """ Test post_ancestry """ self.clair._request = Mock(autospec=True) ancestry = GenericAncestry("ubuntu", "Docker", [ Layer("aaaaa", "hash_aaaaa", "path_aaaaa"), Layer("bbbbb", "hash_bbbbb", "path_bbbbb") ]) self.clair.post_ancestry(ancestry) self.clair._request.assert_any_call('POST', self.clair._CLAIR_POST_URI, json={ 'Layer': { 'Name': 'aaaaa', 'Path': 'path_aaaaa', 'Format': 'Docker' } }) self.clair._request.assert_any_call('POST', self.clair._CLAIR_POST_URI, json={ 'Layer': { 'Name': 'bbbbb', 'Path': 'path_bbbbb', 'Format': 'Docker', 'ParentName': 'aaaaa' } })
def test_delete_ancestry(self): """ Test delete_ancestry """ ancestry = GenericAncestry("ubuntu", "Docker", [ Layer("aaaaa", "hash_aaaaa", "path_aaaaa"), Layer("bbbbb", "hash_bbbbb", "path_bbbbb") ]) with self.assertRaises(PaclairException): self.clair.delete_ancestry(ancestry)
def test_delete_ancestry(self): """ Test delete_ancestry """ self.clair._request = Mock(autospec=True) ancestry = GenericAncestry("ubuntu", "Docker", [ Layer("aaaaa", "hash_aaaaa", "path_aaaaa"), Layer("bbbbb", "hash_bbbbb", "path_bbbbb") ]) self.clair.delete_ancestry(ancestry) self.clair._request.assert_any_call( "DELETE", self.clair._CLAIR_DELETE_URI.format("aaaaa")) self.clair._request.assert_any_call( "DELETE", self.clair._CLAIR_DELETE_URI.format("bbbbb"))
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 __init__(self, docker_image): """ Constructor :param docker_image: docker image """ super().__init__("", "Docker") # headers headers = {'Authorization': "Bearer {}".format(docker_image.token)} partial_path = docker_image.registry.get_blobs_url(docker_image, '{digest}') # Create layers parent = "" for layer in docker_image.get_layers(): self.layers.append(Layer("{}_{}".format(layer, docker_image.short_sha), layer, partial_path.format(digest=layer), headers, parent)) parent = layer self.name = self.layers[-1].name
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)])