Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow overriding environment variables for credstore invocation #9

Merged
merged 1 commit into from
Jun 7, 2018
Merged
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
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.6
FROM python:3.6.4
RUN apt-get update && apt-get -y install \
gnupg2 \
pass \
Expand Down
9 changes: 6 additions & 3 deletions dockerpycreds/store.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,17 +6,19 @@

from . import constants
from . import errors
from .utils import create_environment_dict
from .utils import find_executable


class Store(object):
def __init__(self, program):
def __init__(self, program, environment=None):
""" Create a store object that acts as an interface to
perform the basic operations for storing, retrieving
and erasing credentials using `program`.
"""
self.program = constants.PROGRAM_PREFIX + program
self.exe = find_executable(self.program)
self.environment = environment
if self.exe is None:
raise errors.InitializationError(
'{0} not installed or not available in PATH'.format(
Expand Down Expand Up @@ -65,15 +67,16 @@ def erase(self, server):

def _execute(self, subcmd, data_input):
output = None
env = create_environment_dict(self.environment)
try:
if six.PY3:
output = subprocess.check_output(
[self.exe, subcmd], input=data_input
[self.exe, subcmd], input=data_input, env=env,
)
else:
process = subprocess.Popen(
[self.exe, subcmd], stdin=subprocess.PIPE,
stdout=subprocess.PIPE
stdout=subprocess.PIPE, env=env,
)
output, err = process.communicate(data_input)
if process.returncode != 0:
Expand Down
11 changes: 10 additions & 1 deletion dockerpycreds/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

def find_executable(executable, path=None):
"""
As distutils.spawn.find_executable, but on Windows, looks up
As distutils.spawn.find_executable, but on Windows, look up
every extension declared in PATHEXT instead of just `.exe`
"""
if sys.platform != 'win32':
Expand All @@ -27,3 +27,12 @@ def find_executable(executable, path=None):
return None
else:
return executable


def create_environment_dict(overrides):
"""
Create and return a copy of os.environ with the specified overrides
"""
result = os.environ.copy()
result.update(overrides or {})
return result
8 changes: 8 additions & 0 deletions tests/store_test.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import os
import random
import sys

Expand Down Expand Up @@ -67,3 +68,10 @@ def test_unicode_strings(self):
self.store.erase(key)
with pytest.raises(CredentialsNotFound):
self.store.get(key)

def test_execute_with_env_override(self):
self.store.exe = 'env'
self.store.environment = {'FOO': 'bar'}
data = self.store._execute('--null', '')
assert b'\0FOO=bar\0' in data
assert 'FOO' not in os.environ
22 changes: 22 additions & 0 deletions tests/utils_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import os

from dockerpycreds.utils import create_environment_dict

try:
from unittest import mock
except ImportError:
import mock


@mock.patch.dict(os.environ)
def test_create_environment_dict():
base = {'FOO': 'bar', 'BAZ': 'foobar'}
os.environ = base
assert create_environment_dict({'FOO': 'baz'}) == {
'FOO': 'baz', 'BAZ': 'foobar',
}
assert create_environment_dict({'HELLO': 'world'}) == {
'FOO': 'bar', 'BAZ': 'foobar', 'HELLO': 'world',
}

assert os.environ == base