Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 30 additions & 3 deletions pyhelm/repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
from posixpath import join as urljoin # https://stackoverflow.com/a/15279799
from posixpath import join as urljoin # https://stackoverflow.com/a/15279799


class HTTPGetError(RuntimeError):
Expand Down Expand Up @@ -49,6 +49,7 @@ def __init__(self, repository):
def _semver_sorter(x):
return list(map(int, ''.join(i for i in x['version'] if i in '0123456789.').split('.')))


def _get_from_http(repo_url, file_url, **kwargs):
"""Downloads the Chart's repo index from HTTP(S)"""

Expand All @@ -60,6 +61,7 @@ def _get_from_http(repo_url, file_url, **kwargs):
raise HTTPGetError(file_url, index.status_code, index.text)
return index.content


def _get_from_s3(repo_url, file_url):
"""Download the index / Chart from S3 bucket"""
import boto3.s3
Expand Down Expand Up @@ -94,9 +96,30 @@ def _get_from_s3(repo_url, file_url):
else:
raise


def _get_from_gcs(repo_url, file_url):
"""
Download the index / Chart from GCS bucket

https://bucket-name.storage.googleapis.com/
"""
from google.cloud import storage

repo_url_parsed = urlparse(repo_url)
bucket_name = repo_url_parsed.netloc

file_url_parsed = urlparse(file_url)
file_name = file_url_parsed.path.strip("/")

storage_client = storage.Client()
bucket = storage_client.get_bucket(bucket_name)
blob = bucket.blob(file_name)

return blob.download_as_string()


def _get_from_repo(repo_scheme, repo_url, file_url, **kwargs):
"""Wrap download from specific repository"""

if repo_scheme == 's3':
return _get_from_s3(
repo_url,
Expand All @@ -108,9 +131,12 @@ def _get_from_repo(repo_scheme, repo_url, file_url, **kwargs):
file_url,
**kwargs
)
elif repo_scheme == "gs":
return _get_from_gcs(repo_url, file_url)
else:
raise SchemeError(repo_scheme.upper())


def repo_index(repo_url, headers=None):
"""Downloads the Chart's repo index"""
repo_scheme = urlparse(repo_url).scheme
Expand All @@ -124,6 +150,7 @@ def repo_index(repo_url, headers=None):
)
)


def from_repo(repo_url, chart, version=None, headers=None):
"""Downloads the chart from a repo to a temporary dir, the path of which is
determined by the platform.
Expand Down Expand Up @@ -165,7 +192,7 @@ def git_clone(repo_url, branch='master', path=''):
"""clones repo to a temporary dir, the path of which is determined by the platform"""

_tmp_dir = tempfile.mkdtemp(prefix='pyhelm-')
repo = Repo.clone_from(repo_url, _tmp_dir, branch=branch)
Repo.clone_from(repo_url, _tmp_dir, branch=branch)

return os.path.join(_tmp_dir, path)

Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ requests
PyYAML
boto3
botocore
google-cloud-storage==1.20.0
22 changes: 22 additions & 0 deletions tests/test_repo.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,25 @@ def test_get_from_s3_client_error(self, mocked_s3client):
{'Error': {'Code': ''}}, '')
with self.assertRaises(ClientError):
repo._get_from_repo('s3', 'test', 'foo')

def test_get_from_gcs_ok(self, mocked_gcsclient):
repo._get_from_repo('gcs', 'test', 'bar')
mocked_gcsclient.return_value.get_object.assert_called()

def test_get_from_gcs_repo_error(self, mocked_gcsclient):
mocked_gcsclient.return_value.get_object.side_effect = ClientError(
{'Error': {'Code': 'NoSuchBucket'}}, '')
with self.assertRaises(repo.RepositoryError):
repo._get_from_repo('gcs', 'test', 'foo')

def test_get_from_gcs_chart_error(self, mocked_gcsclient):
mocked_gcsclient.return_value.get_object.side_effect = ClientError(
{'Error': {'Code': 'NoSuchKey'}}, '')
with self.assertRaises(repo.ChartError):
repo._get_from_repo('gcs', 'test', 'foo')

def test_get_from_gcs_client_error(self, mocked_gcsclient):
mocked_gcsclient.return_value.get_object.side_effect = ClientError(
{'Error': {'Code': ''}}, '')
with self.assertRaises(ClientError):
repo._get_from_repo('gcs', 'test', 'foo')